Подтвердить что ты не робот

Поиск с помощью WebAPI

Я создал класс веб-API для моей модели Customer. У меня есть стандартные методы (GET, POST, PUT, DELETE). Проблема в том, что я хочу реализовать другой метод GET, который является поиском. Что-то вроде этого:

[HttpGet]
public IEnumerable<Customer> Search(string id)
{
    var customers = customerRepository.Search(id);
    return customers;
}

Метод поиска выполняет поиск на основе номера учетной записи моих клиентов, используя метод .Contains().

Проблема в том, когда я перехожу к: mySite.com/api/Customers/Search/123 Я получаю 404. Что я здесь делаю неправильно?

4b9b3361

Ответ 1

В соответствии с настройкой маршрута по умолчанию разрешены только стандартные имена действий контроллера (RESTful и диспетчеризация выполняются на основе HTTP-глагола). Если вы хотите нарушить соглашения RESTful и использовать некоторые пользовательские имена действий, вам нужно будет изменить настройку маршрута, чтобы включить имя действия в URL: api/{controller}/{action}/{id}. Теперь вы можете отправить запрос на /api/Customers/Search/123, который будет вызывать действие поиска на контроллере API клиентов.

Ответ 2

В то время как ответы Дарина всегда высоки, этот вопрос действительно выиграет от ответа, объясняющего, как поиск, пейджинг и фильтрация должны выполняться в любом API и как это должно быть сделано с использованием самой последней версии Web API (v2).

Это сообщение, которое я считаю хорошим ресурсом по этому вопросу (технология не поддается): http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

В ответе также должно быть отражено то, что нового в ASP.NET Web API v2, потому что ответ Дарина довольно старый.

Поскольку этот вопрос возникает наверху, когда вы делаете поиск в Google для поиска asp.net web api, я попытаюсь объяснить здесь несколько вещей.

Чтобы максимально приблизиться к принципам REST с последней версией ASP.NET Web API (v2), следует серьезно рассмотреть маршрутизацию атрибутов, которая была введена в последней версии. Очень сложно выполнить маршрутизацию RESTful со старой классической маршрутизацией на основе конвенции (в global.asax.cs или RouteConfig.cs).

Вы должны больше узнать об этом здесь http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

Теперь, чтобы подробно описать, как реализовать специфику, о которой вы спрашиваете.

Наиболее распространенной практикой является раскрытие этих типов функциональности с помощью параметров строки запроса.

В соответствии с принципами REST у вас должна быть одна конечная точка для ресурса ваших клиентов, например

/api/customers

Чтобы достичь этого, вы должны украсить свое действие GetCustomers() в вашем контроллере веб-API, например

[HttpGet]
[Route("/api/customers")]
public HttpResponseMessage GetCustomers(string q="", string sortBy="", string sortDirection="", bool active=true, ...)
{ 
// q = being optional search query
// sortBy = optional sort by column/property
// sortDirection = optional sort direction
// active = filter on 'active' column/property
// ... other filters may be applicable
}

Вы бы применили это действие близко к тому, что вы сделали в классическом MVC, если хотите предоставить отфильтрованные представления.

Я бы только представил новые контроллеры и пользовательские действия, если это действительно необходимо, для некоторых пользовательских случаев края.

в отношении комментария о строго типизированном объекте SearchFilter, объясните, что это не будет работать из коробки, потому что связующее устройство по умолчанию не будет связываться с этим классом при использовании запросов GET.

Таким образом, я либо выберу эти свойства из класса SearchFilter, либо поместил их в самом действии, чтобы они связывались с помощью связующего кода строки запроса или использовали связующее [FromBody], если вы хотите связать его с телом запроса. По http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

НТН