2012-09-27 14 views
24

Estoy intentando configurar el enrutamiento en mi proyecto MVC4 WebAPI.Enrutamiento basado en el nombre del parámetro de cadena de consulta

Quiero ser capaz de buscar productos en función de su nombre o su tipo, así:

/api/products?name=WidgetX - devuelve todos los productos mencionados WidgetX /api/products?type=gadget - devuelve todos los productos de tipo de aparato

Las rutas están configurado de esta manera:

config.Routes.MapHttpRoute(
    name: "Get by name", 
    routeTemplate: "api/products/{name}", 
    defaults: new { controller = "ProductSearchApi", action = "GetProductsByName", name = string.Empty } 
); 

config.Routes.MapHttpRoute(
    name: "Get by type", 
    routeTemplate: "api/products/{type}", 
    defaults: new { controller = "ProductSearchApi", action = "GetProductsByType", type = string.Empty } 
); 

el problema es que el nombre del parámetro de cadena de consulta parece ser ignorado por lo que la primera ruta es siempre la que se utiliza, sin tener en cuenta el nombre del parámetro de cadena de consulta. ¿Cómo puedo modificar mi ruta para hacerlo bien?

Respuesta

30

Lo que necesita es a continuación simplemente sólo una ruta debido a la cadena de consulta no se utiliza como parámetros de ruta:

config.Routes.MapHttpRoute(
    name: "Get Products", 
    routeTemplate: "api/products", 
    defaults: new { controller = "ProductSearchApi" } 
); 

Y, a continuación, definir dos métodos como a continuación:

GetProductsByName(string name) 
{} 

GetProductsByType(string type) 
{} 

enrutamiento mecanismo es inteligente suficiente para enrutar su url a la acción correcta en función del nombre de la cadena de consulta, ya sea el mismo con los parámetros de entrada. Por supuesto, en todos los métodos con prefijo son Get

Es posible que tenga que leer esto: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

0

intente cambiar string.Empty para RouteParameter.Optional

+0

RouteParameter me haría utilicen URL como/productos/ABC que por supuesto no cumplirían con el requisito. Necesito poder usar los parámetros de cadena de consulta. – rickythefox

4

No es necesario incluir sus parámetros de consulta en la ruta. Sólo debe haber una sencilla hoja de ruta para cubrir los métodos HTTP en todas sus ApiControllers:

routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
); 

La única vez que es necesario ajustar las rutas es si desea mover un parámetro en el camino real, que se no parece estar haciendo. A continuación, el método de GET http para buscar por dos campos serían:

public IEnumerable<Product> Get(string name, string type){ 
    //..your code will have to deal with nulls of each parameter 
} 

Si desea buscar explícitamente por un campo a la vez, entonces usted debe considerar el uso de diferentes controladores para diferentes propósitos. Es decir, un SearchProductByTypeController que tiene un solo método Get(string type). La ruta sería/api/SearchProductByTypeController? Type = gadget

+0

Gracias, a veces el problema no está en el código sino en la arquitectura. ;) – rickythefox

+1

¿Qué tipo de recurso es 'SearchProductByTypeController'? :PAG –

0

¿Estás seguro de que los controladores están bien? Quiero decir, el nombre de los params.

public string GetProductsByName(string name) 
    { 
     return "Requested name: " + name; 
    } 

    public string GetProductsByType(string type) 
    { 
     return "Requested type: " + type; 
    } 
Cuestiones relacionadas