I have 2 POCOs, Lessons and Traits with int PKs.
I have navigation properties set up such that I can successfully $expand
like so:
http://localhost:54321/odata/Lessons?$expand=Traits
http://localhost:54321/odata/Traits?$expand=Lessons
My final hurdle in migrating project from Net 461 to .Net Core 2 is Creating Relationships.
Specifically, when I try to call the following method, with the following request, I get a 404.
[AcceptVerbs("POST", "PUT")]
public async Task<IActionResult> CreateRef(
[FromODataUri] int key, string navigationProperty, [FromBody] Uri link)
{
.... Do Work
}
Postman request:
http://localhost:54321/odata/Lessons(1)/Traits/$ref
body:
{
"@odata.id":"http://localhost:54321/OData/traits(1)"
}
The following is my Startup.Configure
method.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
var builder = ConfigureOdataBuilder(app);
app.UseMvc(routeBuilder =>
{
routeBuilder.Select().Expand().Filter().OrderBy().MaxTop(null).Count();
routeBuilder.MapODataServiceRoute("ODataRoute", "odata", builder.GetEdmModel());
// Work-around for #1175
routeBuilder.EnableDependencyInjection();
routeBuilder.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}"); // enable mvc controllers
});
}
private ODataConventionModelBuilder ConfigureOdataBuilder(IApplicationBuilder app)
{
var builder = new ODataConventionModelBuilder(app.ApplicationServices);
builder.EntitySet<Lessons>(nameof(Lessons));
builder.EntitySet<Traits>(nameof(Traits));
return builder;
}
Question: How do I reach this controller method?
Things I have tried,
[ODataRoute("Lessons({key})/{navigationProperty}")]
OData stands for Open Data Protocol which helps to build and consuming of RESTFul APIs. It is an ISO/IEC-approved and OASIS standard. OData will take care of various approaches to RESTful API like Status codes, URL conventions, request and response headers, media types, query options, payload formats, etc.
For this tutorial, we'll use Entity Framework (EF) Code First to create the back-end database. Web API OData does not require EF. Use any data-access layer that can translate database entities into models.
The Open Data Protocol (OData) is a data access protocol for the web. OData provides a uniform way to query and manipulate data sets through CRUD operations (create, read, update, and delete).
To define an OData service, simply derive from ODataController. This is a base class for OData controllers that support writing and reading data using the OData formats.
It was a long way, but I finally found the answer.
[ODataRoute("lessons({lessonId})/traits({traitId})/$ref")]
public IActionResult CreateRef([FromODataUri] int lessonId, [FromODataUri] int traitId)
{
//do work
}
Important: You have to call the id-params as I did. Don´t just call them Id - otherwise you´ll get a 404.
One more thing...
For those who tried the way from the microsoft docs - the Api-Names changed.. You don´t need them for this task, but if you have to convert an Uri to an OData-Path, here is an Uri-Extension doing this for you:
public static Microsoft.AspNet.OData.Routing.ODataPath CreateODataPath(this Uri uri, HttpRequest request)
{
var pathHandler = request.GetPathHandler();
var serviceRoot = request.GetUrlHelper().CreateODataLink(
request.ODataFeature().RouteName,
pathHandler,
new List<ODataPathSegment>());
return pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());
}
If you have an Uri like this: http://localhost:54321/OData/traits(1)
you can split this into OData-segments to get e.g. the navigation: returnedPath.NavigationSource
or the specified key: returnedPath.Segments.OfType<KeySegment>().FirstOrDefault().Keys.FirstOrDefault().Value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With