Wie behandelt ASP.NET Web.api zwei Methoden mit Namen, die mit GET beginnen?

7

Ich schaue mir das folgende Tutorial von Microsoft an. Gemäß diesem Tutorial

  

Im ersten Beispiel entspricht "products" dem angegebenen Controller   ProdukteController. Die Anfrage ist eine GET-Anfrage, also das Framework   sucht nach einer Methode auf ProductsController, deren Name mit beginnt   "Bekommen...". Außerdem enthält der URI nicht die optionale {id}   Segment, so dass das Framework nach einer Methode ohne Parameter sucht. Das   Die Methode ProductsController :: GetAllProducts erfüllt alle diese Anforderungen   Anforderungen.

Was passiert, wenn es zwei Methoden gibt, wie GetAllProducts () und GetSoldProducts ()? Beide haben keine Parameter.

Ihr erstes Web API-Lernprogramm

    
WinFXGuy 18.05.2012, 19:28
quelle

3 Antworten

8

Unter der Annahme, dass Sie die Standardrouten verwenden, lautet die kurze Antwort: Die zuerst definierte Methode (oben) Ihrer Klasse wird aufgerufen. Die andere Methode ist nicht zugänglich.

  

HINWEIS: Die Beta verhielt sich wie oben für "übereinstimmende Mehrfachmethoden" - die RC & amp; Release-Version ist ein bisschen mehr OCD. Wenn mehrere potenzielle Übereinstimmungen vorhanden sind, wird ein Fehler ausgegeben. Diese Änderung beseitigt die Verwirrung mehrerer mehrdeutiger Übereinstimmungen. Gleichzeitig reduziert es unsere Fähigkeit, REST- und RPC-Schnittstellen in demselben Controller zu mischen, und verlässt sich dabei auf die Reihenfolge & amp; überlappende Routen.

Diebstahl frei von einen anderen Beitrag, den ich zum Thema geschrieben habe :

WebAPI Matching Semantic

Die von WebAPI verwendete passende Semantik ist ziemlich einfach.

  1. Es entspricht dem Namen der Aktion mit dem Verb (Verb = get? Suche nach Methode beginnt mit "get")
  2. Wenn ein Parameter übergeben wird, sucht die API eine Aktion mit einem Parameter

Also stimmt in Ihrem Codebeispiel eine GET-Anfrage ohne Parameter mit der Funktion Get*( ) ohne Parameter überein. Ein Get containing und ID sucht nach einem Get***(int id) .

Beispiele

Während die übereinstimmende Semantik einfach ist, erzeugt sie einige Verwirrungen für MVC-Entwickler (zumindest für diesen Entwickler). Schauen wir uns einige Beispiele an:

Ungerade Namen - Ihre Methode kann beliebig benannt werden, solange sie mit "get" beginnt. So können Sie im Falle eines Widget-Controllers Ihre Funktionen GetStrawberry() benennen und sie werden weiterhin abgeglichen. Stellen Sie sich das Matching so vor: methodname.StartsWith("Get")

Mehrere übereinstimmende Methoden - Was passiert, wenn Sie zwei Methoden ohne Parameter haben? GetStrawberry() und GetOrange() . Soweit ich das beurteilen kann, gewinnt die Funktion, die in Ihrem Code zuerst (oben in der Datei) definiert ist, seltsam. Dies hat den Nebeneffekt, dass einige Methoden in Ihrem Controller nicht erreichbar sind (zumindest mit den Standardrouten) .... Fremder.

AKTUALISIEREN

@WinFXGuy - Das war ein bisschen lang, um einen Kommentar zu schreiben, aber ...

Sprich nicht voreilige Schlüsse! Ich habe versucht, deine Frage zu beantworten, aber das ist nur die halbe Wahrheit. Es gibt viele Möglichkeiten, das Standardverhalten zu ändern.

Zuerst unterstützt WebAPI einen Großteil der oData Spezifikation. Wenn Sie eine IQueryable auf Ihren Controller übertragen, werden oData-Parameter automatisch in das Abfrageobjekt integriert. Es enthält Parameter wie $filter , $top und $skip . Also kannst du in deinem Fall eine Methode schreiben und etwas wie $filter=sale_date neq null weitergeben.

Zusätzlich können Sie das Attribut [ResultLimit] anwenden, um zu verhindern, dass Menschen nach 15 Milliarden Datensätzen fragen.

Zweite Sie können die Routen ändern. Die Standardrouten zielen auf eine REST-konforme API, in der Sie in der Regel 1 Controller pro Entity haben. Sie können die Routen ändern und es RPC-Stil machen.

Wenn Sie sich meinen verlinkten Post ansehen, erkläre ich, wie ich die Standard-Routenbindung beibehalten, 'Unterordner' hinzugefügt und auch zusätzliche Methodenaufrufe für Szenarios erlaubt habe, wo ich GetAllProducts() und GetSoldProducts() benötigt habe.

    
EBarr 18.05.2012, 19:35
quelle
11

Für dieses spezielle Problem gibt es zwei mögliche Lösungen:

  1. Wenn Sie MapHttpRoute aufrufen, müssen Sie den Namen der Aktion angeben. (Ich verwende die Self-Hosting-Syntax):

    %Vor%

    So würde Ihr http-Client rufen:

    api/products/GetAllProducts ODER api/GetAllProducts api/products/GetSoldProducts ODER api/GetSoldProducts

    Siehe: Ссылка

  2. Platzieren Sie jede Methode in einem separaten Controller (ProductsController, SoldProductsController). Sie würden also api/products und api/soldproducts aufrufen, um Ihre Ergebnisse zu erhalten.

Ähnliches Thema ... In der Situation, in der Sie mehrere Get-Aktionen mit einem einfachen primitiven Argument des gleichen Typs haben, prüft die ASP.NET-Web-API den Namen des Arguments, um die überladene Aktion aufzulösen.

Zum Beispiel, wenn Sie zwei Aktionen haben:

%Vor%

Ihr http-Client kann

aufrufen %Vor%

und die Routing-Engine ruft die richtige Aktion auf.

    
Lee Grissom 21.06.2012 20:54
quelle
4

Hinzufügen einer Antwort, um anzuzeigen, dass die neueste Version der Web-API das Attribut [Route] nativ unterstützt

%Vor%     
hunter 12.05.2015 17:27
quelle