web-dev-qa-db-ja.com

ASP.NET Web APIのオプションのクエリ文字列パラメータ

次のWebAPIメソッドを実装する必要があります。

/api/books?author=XXX&title=XXX&isbn=XXX&somethingelse=XXX&date=XXX

すべてのクエリ文字列パラメータをnullにすることができます。つまり、呼び出し元は0から5つのパラメーターすべてを指定できます。

In MVC4 beta私は以前以下のことをしていました。

public class BooksController : ApiController
{
    // GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
    public string GetFindBooks(string author, string title, string isbn, string somethingelse, DateTime? date) 
    {
        // ...
    }
}

MVC4 RCはこれ以上動作しません。私が5つより少ないパラメータを指定するならば、それは言っている404で答えます:

要求に一致するコントローラ「Books」でアクションが見つかりませんでした。

URLルーティングでオプションのパラメータを指定しなくても、以前のように動作させるための正しいメソッドシグネチャは何ですか?

195
frapontillo

この問題はMVC4の通常のリリースで修正されています。今、あなたはできる:

public string GetFindBooks(string author="", string title="", string isbn="", string  somethingelse="", DateTime? date= null) 
{
    // ...
}

そしてすべてが箱から出してうまくいくでしょう。

287
frapontillo

Vijayが示唆しているように、単一のモデルとして複数のパラメータを渡すことは可能です。 FromUriパラメータ属性を使用する場合、これはGETに対して機能します。これは、クエリパラメータからモデルを埋めるようにWebAPIに指示します。

その結果、たった1つのパラメータでよりきれいなコントローラの動作が得られます。詳細については参照してください: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

public class BooksController : ApiController
  {
    // GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
    public string GetFindBooks([FromUri]BookQuery query)
    {
      // ...
    }
  }

  public class BookQuery
  {
    public string Author { get; set; }
    public string Title { get; set; }
    public string ISBN { get; set; }
    public string SomethingElse { get; set; }
    public DateTime? Date { get; set; }
  }

プロパティが競合しない限り、複数のパラメータもサポートされています。

// GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01
public string GetFindBooks([FromUri]BookQuery query, [FromUri]Paging paging)
{
  // ...
}

public class Paging
{
  public string Sort { get; set; }
  public int Skip { get; set; }
  public int Take { get; set; }
}

更新
値がオプションであることを確認するために、モデルプロパティに参照型またはnull許容値(例:int?)を必ず使用してください。

75
Andrew C

以下のようにすべてのパラメータに初期デフォルト値を使用

public string GetFindBooks(string author="", string title="", string isbn="", string  somethingelse="", DateTime? date= null) 
{
    // ...
}
61
Muhammad Amin

複数のパラメータを渡したい場合は、複数のパラメータを渡す代わりにモデルを作成できます。

パラメータを渡したくない場合は、その中でスキップしてもかまいません。コードはきれいできれいに見えます。

1
vijay

'optional'として宣言されていないパラメーターにはデフォルト値を指定できません

 Function GetFindBooks(id As Integer, ByVal pid As Integer, Optional sort As String = "DESC", Optional limit As Integer = 99)

あなたのWebApiConfig

 config.Routes.MapHttpRoute( _
          name:="books", _
          routeTemplate:="api/{controller}/{action}/{id}/{pid}/{sort}/{limit}", _
          defaults:=New With {.id = RouteParameter.Optional, .pid = RouteParameter.Optional, .sort = UrlParameter.Optional, .limit = UrlParameter.Optional} _
      )
0
Rizwan Mumtaz