2012-07-25 31 views
13

He hecho una clase API web para mi modelo Customer. Tengo los métodos estándar (GET, POST, PUT, DELETE). El problema es que quiero implementar otro método GET que sea una búsqueda. Algo como esto:Buscando con WebAPI

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

El método de búsqueda realiza una búsqueda basada en el número de cuenta de mis clientes, utilizando el método de .Contains().

El problema es que cuando navego a: mySite.com/api/Customers/Search/123 obtengo un 404. ¿Qué estoy haciendo mal aquí?

Respuesta

7

Según la configuración de ruta predeterminada, solo se permiten los nombres de acción del controlador estándar (los RESTful y el envío se realiza en función del verbo HTTP). Si desea violar las convenciones RESTful y usar algunos nombres de acción personalizados, deberá modificar la configuración de la ruta para incluir el nombre de la acción en la url: api/{controller}/{action}/{id}. Ahora puede enviar una solicitud al /api/Customers/Search/123 que invocará la acción de búsqueda en el controlador API de clientes.

+0

¿Cómo voy a lograr esto usando una forma REST entonces? Como no puedo usar otro método GET ... – CallumVass

+2

Usted crea otro controlador: SearchProductsContoller o lo que sea y luego usa la acción Obtener dentro de él. –

+0

Ahh ... justo como pensaba, ¿entonces eso es lo que normalmente pasaría? ¿Un nuevo controlador para cada solicitud GET adicional que pueda necesitar? – CallumVass

48

Mientras que las respuestas de Darin siempre son de alta calidad, esta pregunta se beneficiaría de una respuesta que explique cómo la búsqueda, la búsqueda y el filtrado deben realizarse en cualquier API y cómo se debe hacer utilizando la versión más actual de la API web (v2).

Este es un puesto que considero un buen recurso en la materia (indenpendent tecnología): http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

La respuesta también debe reflejar lo que hay de nuevo en ASP.NET Web API v2 porque la respuesta de Darin es bastante antiguo.

Dado que esta pregunta aparece en la parte superior cuando se hace una búsqueda en Google de "asp.net web api searching", trataré de explicar algunas cosas aquí.

Para acercarse lo más posible a los principios de REST con la última versión de ASP.NET Web API (v2), se debe considerar seriamente el enrutamiento de atributos que se introdujo en la última versión. Es muy difícil lograr un enrutamiento RESTful con el enrutamiento basado en convenciones antiguo y clásico (en global.asax.cs o RouteConfig.cs).

usted debe leer más sobre esto aquí http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

Ahora, para entrar en detalles de cómo implementar las características específicas que preguntar.

La práctica más común es exponer estos tipos de funcionalidad a través de parámetros de cadena de consulta.

principios por REST, que deben tener un punto final para el recurso clientes, por ejemplo

/api/customers 

Para lograr esto, se decora tus GetCustomers() la acción en el controlador de API Web como esto

[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 
} 

Implementará esta acción estrechamente con lo que hizo en MVC clásico si desea proporcionar Vistas filtradas.

Solo presentaría nuevos controladores y acciones personalizadas si es realmente necesario, para algunos casos de bordes personalizados.

en lo que respecta a un comentario sobre SearchFilter objeto fuertemente tipado, explique que esto no funcionará de la caja porque el enlazador de modelo predeterminado no se vinculará a esta clase cuando se utilizan solicitudes GET.

Así que quitaría esas propiedades de la clase SearchFilter y las pondría en la acción misma para que se enlazaran a través de la carpeta de cadenas de consulta o utilizara el cuaderno [FromBody] si desea enlazar desde el cuerpo de la solicitud. Según http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

HTH

+0

Fantástica respuesta, agradecer la nueva respuesta a una pregunta anterior. –