OData v4 on .Net Core 1.1缺失/ $元数据

时间:2017-02-12 21:05:38

标签: c# asp.net-web-api asp.net-core odata .net-core

使用.net Core 1.1和Microsoft.AspNetCore.OData库,我能够使用我的简单控制器来处理OData端点以执行get,$ expand和其他查询。但是,我无法让它返回要返回的$元数据。这个问题($Metadata with WebAPi OData Attribute Routing Not Working)是针对同一个问题的,但是自从发布以来.Net API已经发生了变化。

是否需要启用设置,标记或其他内容?

这(http://localhost:52315/odata)似乎返回元数据

}

这个(http://localhost:52315/odata/ $元数据)给了我错误:

{
  "@odata.context":"http://localhost:52315/odata/$metadata","value":[
    {
      "name":"Users","kind":"EntitySet","url":"Users"
    },{
      "name":"HelloComplexWorld","kind":"FunctionImport","url":"HelloComplexWorld"
    }
  ]
}

我的Startup.cs看起来像这样:

An unhandled exception occurred while processing the request.
NotSupportedException: No action match template '$metadata'
in 'MetadataController'

Microsoft.AspNetCore.OData.Routing.Conventions.DefaultODataRoutingConvention.SelectAction(RouteContext routeContext)

注意:我可以通过在我的ConfigureServices(...)方法的开头添加它来解决它,虽然看起来错误,因为$ metadata支持应该是核心平台的一部分。

public void Configure(IApplicationBuilder app) {
   app.UseDeveloperExceptionPage();
   app.UseOData("odata");
   app.UseMvcWithDefaultRoute();
}

public void ConfigureServices(IServiceCollection services) {
    services.AddMvc().AddWebApiConventions();
    services.AddSingleton<ISampleService, ApplicationDbContext>();
    services.AddOData<ISampleService>(builder =>
    {
         builder.Namespace = "Sample";
         builder.EntityType<ApplicationUser>();
         builder.EntityType<Product>();
         builder.Function("HelloComplexWorld").Returns<Permissions>();
    });
}

2 个答案:

答案 0 :(得分:1)

我今天重新审视了这一点,并使用Microsoft.AspNetCore.OData.vNext 6.0.2-alpha-rtm软件包取得了更大的成功。引用this示例,元数据和默认OData路由按预期工作。我的最小配置是:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddOData();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        var modelBuilder = new ODataConventionModelBuilder();
        modelBuilder.EntitySet<Document>("Documents");

        app.UseMvc(builder =>
        {
            builder.MapODataRoute("odata", modelBuilder.GetEdmModel());
        });
    }

答案 1 :(得分:0)

/ odata / $ metadata 路由应返回“服务数据模型的XML表示”(EDMX)(根据the OData v4 Web API documentation)。这与服务根 / odata / 不同,后者返回OData服务发布的资源的顶级描述(如示例所示)。

我使用预发行版Microsoft.AspNetCore.OData 1.0.0-rtm-00015遇到了同样的问题,因为还没有正式版本(see open issue on OData Web API repo)。

为了说明这一点,您可以手动发出元数据,如下面的粗略示例所示。 (您可以在OData / odata.net GitHub仓库中找到InMemoryMessage类。)

但是,我建议等待OData ASP.NET Core的官方发布,因为引用上述问题,“分支仍处于早期阶段,一旦我们的架构最终完成,我们可能采取不同的方法” 。所以事情可能会发生变化...... $元数据肯定应该“开箱即用”!

        app.Use((context, func) =>
        {
            if (context.Request.Path.StartsWithSegments(new PathString("/data/v1/$metadata"), StringComparison.OrdinalIgnoreCase))
            {
                var model = app.ApplicationServices.GetService<IEdmModel>();

                MemoryStream stream = new MemoryStream();
                InMemoryMessage message = new InMemoryMessage() {Stream = stream};

                ODataMessageWriterSettings settings = new ODataMessageWriterSettings();

                ODataMessageWriter writer = new ODataMessageWriter((IODataResponseMessage)message, settings, model);
                writer.WriteMetadataDocument();

                string output = Encoding.UTF8.GetString(stream.ToArray());

                return context.Response.WriteAsync(output);
            }

            return func();
        });