Необязательные параметры строки запроса в ASP.NET Web API

мне нужно реализовать следующий метод WebAPI:

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

все параметры строки запроса могут быть null. То есть вызывающий объект может указать от 0 до всех 5 параметров.

на MVC4 с бета я делал следующее:

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 говорю:

на контроллере "книги" не найдено никаких действий, которые соответствует запросу.

какова правильная сигнатура метода, чтобы заставить ее вести себя так, как она привыкла, без необходимости указывать необязательный параметр в маршрутизации URL?

5 ответов


эта проблема была исправлена в регулярном выпуске MVC4. Теперь вы можете сделать:

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

и все будет работать из коробки.


можно передать несколько параметров в одной модели, как виджей предложил. Это работает для GET при использовании атрибута параметра FromUri. Это говорит WebAPI заполнить модель из параметров запроса.

результат более чистое действие регулятора с как раз одиночным параметром. Для получения дополнительной информации см.: 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; }
}

обновление:
Чтобы убедиться, что значения являются необязательными, обязательно используйте ссылочные типы или nullables (ex. int?) для свойств моделей.


использовать исходные значения по умолчанию для всех параметров, как показано ниже

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

Если вы хотите передать несколько параметров, вы можете создать модель вместо передачи нескольких параметров.

Если вы не хотите передавать какой-либо параметр, вы можете пропустить его, и ваш код будет выглядеть аккуратно и чисто.


значения по умолчанию не могут быть предоставлены для параметров, которые не объявлены'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} _
      )