迁移到.Net Core的CreateRef方法导致404,如何使用.Net Core在OData中实现Create Relationships

时间:2018-03-26 13:16:55

标签: asp.net-core odata

我有两个POCO,课程和特征与int PKs。 我设置了导航属性,以便我可以成功地$expand

  • http://localhost:54321/odata/Lessons?$expand=Traits
  • http://localhost:54321/odata/Traits?$expand=Lessons

将Net 461迁移到.Net Core 2的最后一个障碍是Creating Relationships

具体来说,当我尝试使用以下请求调用以下方法时,我得到404。

[AcceptVerbs("POST", "PUT")]        
public async Task<IActionResult> CreateRef(
    [FromODataUri] int key, string navigationProperty, [FromBody] Uri link)
{
    ....  Do Work
}

邮差要求:

http://localhost:54321/odata/Lessons(1)/Traits/$ref

体:

 {
    "@odata.id":"http://localhost:54321/OData/traits(1)"
 }

以下是我的Startup.Configure方法。

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;
}

问题:如何使用此控制器方法?

我尝试过的事情,

1 个答案:

答案 0 :(得分:2)

很长的路要走,但我终于找到了答案。

[ODataRoute("lessons({lessonId})/traits({traitId})/$ref")]
public IActionResult CreateRef([FromODataUri] int lessonId, [FromODataUri] int traitId)
{
    //do work
}

重要提示:您必须像我一样调用id参数。不要只是将它们称为ID,否则您会得到404。

还有一件事...

对于那些尝试过Microsoft Docs方式的用户-更改了Api名称。.您不需要它们来完成此任务,但是如果您必须将Uri转换为OData-Path,则这里有一个Uri-扩展程序为您执行此操作:

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());
}

如果您有一个这样的Uri:http://localhost:54321/OData/traits(1),则可以将其拆分为OData段以获取例如导航:returnedPath.NavigationSource或指定键:returnedPath.Segments.OfType<KeySegment>().FirstOrDefault().Keys.FirstOrDefault().Value