Дополнительные параметры в ASP.NET Web API

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

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

Все параметры могут быть нулевыми, то есть вызывающий может указывать от 0 до всех 5 параметров.

В MVC4 beta​​strong > я использовал следующее:

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?

Ответ 1

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

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

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

Ответ 2

Возможно передать несколько параметров в виде одной модели, как предполагалось. Это работает для 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; }
}

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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