Ustawienia opcjonalne ciąg kwerendy w ASP.NET web API

muszę zrealizować następującą metodę WebAPI:

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

wszystkie parametry wiersza zapytania mogą być null. Czyli wywołujący może przyznać od 0 do 5 parametrów.

MVC4 beta zrobiłem następujący:

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 już nie zachowuje się tak. Jeśli wybiorę w mniej niż 5 parametrów, odpowie 404 mówię:

na kontrolerze "książki" nie znaleziono żadnych działań, które spełnia życzenie.

jaka jest prawidłowa sygnatura metody, aby zmusić ją zachowywać się tak, jak ona jest przyzwyczajona, bez potrzeby, aby określić parametr opcjonalny, routing URL?


ten problem został rozwiązany w normalnym wydaniu MVC4. Teraz możesz zrobić:

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

i wszystko będzie działać po wyjęciu z pudełka.


można wysłać kilka opcji w jednym modelu, jak vijay zaproponował. To działa dla GET przy użyciu atrybutu opcji FromUri. To mówi do WebAPI wypełnić model z opcji kwerendy.

wynik bardziej czyste działanie regulatora z pojedynczym parametrem. Aby uzyskać więcej informacji, zobacz: 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; }
  }

nawet obsługuje kilka parametrów, aż właściwości nie są w konflikcie.

// 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; }
}

aktualizacja:
Aby upewnić się, że wartości są opcjonalne, należy używać typów referencyjnych lub nullables (ex. int?) dla właściwości modelu.


użyj oryginalnych wartości domyślne dla wszystkich parametrów, jak pokazano poniżej

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

Jeśli chcesz przekazać kilka ustawień, można utworzyć model zamiast wysłać kilka parametrów.

Jeśli nie chcesz wysyłać jakiś parametr, można również pominąć, a twój kod będzie wyglądać schludnie i czysto.


ustawienia domyślne nie mogą być podane dla parametrów, które nie są zadeklarowane'optional'

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

w swoim 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} _
      )