8

私はマイクロソフトからの次のチュートリアルを見ています。このチュートリアルによると、

最初の例では、「products」はProductsControllerという名前のコントローラーと一致します。リクエストはGETリクエストであるため、フレームワークは、名前が「Get...」で始まるProductsController上のメソッドを探します。さらに、URIにはオプションの{id}セグメントが含まれていないため、フレームワークはパラメーターのないメソッドを探します。ProductsController :: GetAllProductsメソッドは、これらの要件をすべて満たしています。

GetAllProducts()とGetSoldProducts()のような2つのメソッドがある場合はどうなりますか?どちらにもパラメータはありません。

最初のWebAPIチュートリアル

4

3 に答える 3

12

この特定の問題には2つの可能な解決策があります。

  1. MapHttpRoute呼び出しを変更して、アクションの名前を指定する必要があります。(私はセルフホスティング構文を使用しています):

        config.Routes.MapHttpRoute(
                "API Route 1",
                "api/{controller}/{action}");
    
        config.Routes.MapHttpRoute(
                "API Route 2",
                "api/{action}",
                new { controller = "products" });
    

    したがって、httpクライアントは次のように呼び出します。

    api/products/GetAllProductsまたはapi/GetAllProducts api/products/GetSoldProductsまたはapi/GetSoldProducts

    参照: http ://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

  2. 各メソッドを別々のコントローラー(ProductsController、SoldProductsController)に配置します。だからあなたは電話api/productsapi/soldproductsてあなたの結果を得るでしょう。


関連トピック...同じタイプの単一のプリミティブ引数を持つ複数のGetアクションがある状況では、ASP.NET Web APIは引数の名前を調べて、呼び出すオーバーロードされたアクションを解決します。

たとえば、2つのアクションがある場合:

GetProductByName(string name) 
GetProductByCategory(string category) 

httpクライアントは呼び出すことができます

api/products?name=hammer 
api/products?category=toys

ルーティングエンジンは正しいアクションを呼び出します。

于 2012-06-21T20:54:59.237 に答える
8

デフォルトルートを使用していると仮定すると、簡単な答えは次のとおりです。クラスの最初に(上部に)定義されたメソッドが呼び出されます。他の方法にはアクセスできません。

注:ベータ版は「複数の方法を一致させる」ために上記のように動作しました-RC&リリースバージョンはもう少しOCDです。一致する可能性のあるものが複数ある場合は、エラーがスローされます。この変更により、複数のあいまいな一致の混乱がなくなります。同時に、順序と重複するルートに依存して、同じコントローラー内でRESTスタイルとRPCスタイルのインターフェイスを混在させる機能が低下します。

私がこのトピックについて書いた別の投稿から自由に盗む:

WebAPIマッチングセマンティック

WebAPIで使用されるマッチングセマンティクスはかなり単純です。

  1. アクションの名前を動詞と一致させます(verb = get? "get"で始まるメソッドを探します)
  2. パラメータが渡された場合、APIはパラメータを使用してアクションを探します

したがって、コードサンプルでは、​​パラメーターのないGETリクエストは、パラメーターのGet*( )ない関数と一致します。含むGetとIDはを探しますGet***(int id)

マッチングセマンティクスは単純ですが、MVC開発者(少なくともこの開発者)にとっては混乱を招きます。いくつかの例を見てみましょう:

奇数名-getメソッドは、「get」で始まる限り、任意の名前を付けることができます。したがって、ウィジェットコントローラーの場合は、関数GetStrawberry()に名前を付けることができますが、それでも一致します。マッチングは次のようなものと考えてください。 methodname.StartsWith("Get")

複数のマッチングメソッド-パラメータのないGetメソッドが2つある場合はどうなりますか? GetStrawberry()およびGetOrange()。私が知る限り、コードで最初に定義された関数(ファイルの先頭)が...strangeに勝ちます。これには、コントローラーの一部のメソッドに到達できなくなるという副作用があります(少なくともデフォルトルートでは)...見知らぬ人。

アップデート

@WinFXGuy-コメントを入れるのに少し時間がかかりましたが...

結論に飛びつくな!私はあなたが提起した質問に答えようとしましたが、それは話の半分にすぎません。デフォルトの動作を変更するためにできることはたくさんあります。

まず、WebAPIはoData仕様の多くをサポートしています。コントローラにバブルIQueryableアップすると、oDataパラメータはクエリオブジェクトと自動的に統合されます。$filter、、、などのパラメータを取り$topます$skip。したがって、あなたの場合、1つのメソッドを記述して、のようなものを渡すことができます$filter=sale_date neq null

さらに、この属性を適用して、[ResultLimit]150億件のレコードを要求する人を防ぐことができます。

次に、ルートを変更できます。デフォルトルートはRESTfulAPIを対象としており、通常、エンティティごとに1つのコントローラーがあります。ルートを変更してRPCスタイルにすることができます。

GetAllProducts()リンクされた投稿を見ると、デフォルトのルートバインディングを維持し、「サブフォルダー」を追加し、必要なシナリオで追加のメソッド呼び出しを許可する方法を説明していますGetSoldProducts()

于 2012-05-18T19:35:55.187 に答える
4

最新バージョンのWebAPIが[Route]属性をネイティブにサポートしていることを反映する回答を追加する

[Route("api/products")]
public IEnumerable<Product> GetAllProducts(){}

[Route("api/products/sold")]
public IEnumerable<Product> GetSoldProducts(){}
于 2015-05-12T17:27:02.963 に答える