2013-08-14 3 views
19

Kann mir jemand erklären, wann ich mein Controller-Formular ODataController vs ApiController erben sollte?ApiController vs ODataController beim Aussetzen von DTOs

Die Frage wird durch die Tatsache verursacht, dass die von ApiController zurückgegebenen Ergebnisse mit OData-Abfrage gefiltert werden können.

Wenn ich QueraybleAttribute auf die Methoden von contoller anwenden, wird die Abfrage verarbeitet, selbst wenn die Aktion IEnumerable zurückgibt.
Ohne dieses Attribut, aber mit dem Aufruf config.EnableQuerySupport(), wird die Abfrage nur verarbeitet, wenn die Methode IQueryable zurückgibt.
Ich denke, es ist kein konsistentes Verhalten. WebAPI documentation and examples bedeutet, dass der Controller von ODataController inerit sein muss. Und ich bin ein wenig verwirrt.
Entweder ApiControlleraccidentally und teilweise unterstützt Teil (mindestens $ überspringen, $ Filter und $ oben) von OData-Protokoll. Oder das ist von Entwurf und ich brauche ODataController für komplette ODataSupport.

Das eigentliche Problem ist, dass mein Dienst DTOs, nicht POCOs exponiert. Es kann keine Eins-zu-Eins-Zuordnung geben. Es muss eine OData-Abfrage für DTOs in eine EF-Abfrage für POCOs konvertiert werden.
Jetzt nur mit OData spielen. Ich rufe Entitäten ab und wandle sie in DTOs um. Zugegebenermaßen ist dies nicht sehr performant, um alle von DB für jede Anfrage zu erhalten, die für Experimente noch tolerierbar ist. Aber es ist definitiv nicht notwendig, alle Entitäten an den Client zurückzugeben, wenn es eine gefilterte Teilmenge von DTOs erfordert.
Die OData-Abfrage wurde sofort mit ApiController und dem Attribut Queryble gestartet, aber die oben erwähnte Inkonsistenz lässt mich etwas falsch machen.

+3

Ich denke, es ist, weil es zusätzliche Funktionen wie Metadaten implementiert ermöglicht WCF Data Services-Client verwendet werden: http://sravi-kiran.blogspot.co.nz/2013/ 08/ConsumingWebApiODataFromNetAndJavaScriptClientApplications.html, http://blogs.msdn.com/b/webdev/archive/2013/01/29/getting-started-with-asp-net-webapi-odata-in-3-simple-steps.aspx, http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api. Web-API (mit Abfrage-Unterstützung) kam Januar 2012 und Web-API-OData im Januar 2013, so dass ich denke, Sie haben Recht mit "Ich brauche ODataController für vollständige ODataSupport" OData-Spezifikation entsprechen. – Michael

Antwort

8

Kann mir jemand erklären, wenn ich mein Controller Form ODataController vs ApiController erben sollte?

Sie würden von ODataController erben wollen, wenn Sie einen Endpunkt verfügbar machen möchten, die dem OData protocol haftet. Wenn Sie etwas anderes tun möchten, beispielsweise einen REST-Endpunkt, erben Sie von ApiController.

Einige Teile des WebAPI-OData-Frameworks, aber keine anderen, ist wahrscheinlich keine gute Idee. Es kann in einigen Fällen, aber wird wahrscheinlich nicht gut in anderen arbeiten. Zum Beispiel können Sie Support anfordern, aber der $ metadata-Endpunkt wird möglicherweise nicht generiert (das ist nur Spekulation, die tatsächlichen Symptome können unterschiedlich sein).

Es klingt, als ob Sie bereits EntityFramework verwenden. Ich weiß, dass es eine Reihe von Beispielen gibt, die zeigen, wie dies als OData-Endpunkt verfügbar gemacht wird.

Wenn Sie dies aus irgendeinem Grund nicht tun möchten, können Sie die Abfrage selbst implementieren. Dies wird kurz an einigen Stellen unter this tutorial behandelt, aber das Wesentliche besteht darin, einen Parameter vom Typ ODataQueryOptions<T> zu Ihrer Aktion hinzuzufügen und die Methoden darauf zu verwenden, um Ihre Ergebnismenge zu filtern. Es kann jedoch sehr mühsam sein, gute Datenbankabfragen für alle möglichen OData-Abfragen zu erstellen. Sie sollten dies also nach Möglichkeit vermeiden.

+0

Danke. Ich habe den Wortlaut meiner Frage geändert. Hoffe es wurde klarer. –

+0

Ich denke, es kann eine gute Idee sein, wenn Sie Ihre Controller in einem eigenen Verzeichnis trennen. Machen Sie einen API-Ordner und einen OData-Ordner in Ihrem Controller-Ordner. Ein Vorteil der Verwendung von OData besteht darin, dass Sie für jedes angeforderte Element keine neue fest codierte linq-Abfrage erstellen müssen. Es ist sehr nützlich für die Abfrage einer einzelnen Entität (nicht verbundene Entitäten). Die abfragende URL generiert automatisch den linq-Ausdruck für Sie. Indem Sie keine neuen linq-Abfragen mehr hinzufügen müssen, vermeiden Sie Code-Pflege und Overhead für Ihr Projekt. – sksallaj

+1

Ich würde APIController für komplexe verbundene Entity-Beziehungen und OData für einfache einzelne Entity-Beziehungen verwenden. – sksallaj