2017-02-12 2 views
0

Mit .net Core 1.1, mit den Microsoft.AspNetCore.OData-Bibliotheken, bin ich in der Lage, einen OData-Endpunkt zu bekommen, der mit meinem einfachen Controller funktioniert, um $ expand und andere Abfragen. Ich kann jedoch nicht die zurückgegebenen $ -Metadaten zurückgeben. Diese Frage ($Metadata with WebAPi OData Attribute Routing Not Working) ist für das gleiche Problem, jedoch haben sich die .Net-APIs seit der Veröffentlichung geändert.

Gibt es eine Einstellung, ein Flag oder etwas anderes, das ich aktivieren muss?

Diese (http://localhost:52315/odata) scheint die Meta-Daten zurück,

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

diese (http://localhost:52315/odata/ $ Metadaten) gibt mir den Fehler:

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) 

Meine Startup.cs wie folgt aussieht:

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

HINWEIS: Ich kann umgehen, indem ich dies zu Beginn meiner Con hinzufügen figureServices (...) Methode, obwohl es falsch scheint $ Metadaten Unterstützung sollte Teil der Kernplattform sein.

app.Use(async (context, next) => { 
    if (0 == string.Compare(context.Request.Path, @"/odata/$metadata", true)) { 
     context.Request.Path = "/odata"; 
    } 
    await next.Invoke(); 
}); 

Antwort

0

Die /OData/$ Metadaten Route "Darstellung des Datenmodells der Dienst eine XML" (EDMX) (nach the OData v4 Web API documentation) zurückkehren. Dies entspricht nicht dem Service-Stamm /odata/, der die Top-Level-Beschreibung der vom OData-Service veröffentlichten Ressourcen zurückgibt (wie in Ihrem Beispiel gezeigt).

Ich stieß auf das gleiche Problem mit der Vorabversion Microsoft.AspNetCore.OData 1.0.0-RTM-00015, da eine offizielle Version noch nicht verfügbar ist (see open issue on OData Web API repo).

Um den Punkt zu verdeutlichen, könnten Sie die Metadaten manuell ausgeben, wie im groben Beispiel unten. (Sie finden die InMemoryMessage-Klasse in der OData/odata.net GitHub-Repo.)

Allerdings würde ich vorschlagen, auf eine offizielle Veröffentlichung von OData ASP.NET Core zu warten, wie aus dem oben genannten Problem, der "Zweig ist noch in einem frühen Stadium und wir können einen anderen Ansatz verfolgen, sobald wir unsere Architektur fertiggestellt haben ". Das kann sich ändern ... und $ Metadaten sollten definitiv "out of the box" funktionieren!

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

revisited ich diese heute und mehr Erfolg hatte das Microsoft.AspNetCore.OData.vNext 6.0.2-alpha-rtm-Paket. Referenzieren this Beispiel, die Metadaten und Standard OData Routing funktionierte wie erwartet. Meine minimale Konfiguration ist:

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