web-dev-qa-db-fra.com

Routage basé sur le nom du paramètre de chaîne de requête

J'essaie de configurer le routage dans mon projet MVC4 WebAPI.

Je veux pouvoir rechercher des produits en fonction de leur nom ou de leur type:

/api/products?name=WidgetX - renvoie tous les produits nommés WidgetX /api/products?type=gadget - renvoie tous les produits de type gadget

Les itinéraires sont configurés comme ceci:

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 }
);

Le problème est que le nom du paramètre de chaîne de requête semble être ignoré, donc la première route est toujours celle utilisée, quel que soit le nom du paramètre de chaîne de requête. Comment puis-je modifier mon itinéraire pour le faire correctement?

25
rickythefox

Vous n'avez besoin que d'un seul itinéraire ci-dessous car la chaîne de requête n'est pas utilisée comme paramètres de routage:

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

Et puis définissez deux méthodes comme ci-dessous:

GetProductsByName(string name)
{}

GetProductsByType(string type)
{}

Le mécanisme de routage est intelligent suffisamment pour acheminer votre URL vers votre action correcte en fonction du nom de la chaîne de requête, qu'il en soit de même avec les paramètres d'entrée. Bien sûr, toutes les méthodes avec préfixe sont Get

Vous devrez peut-être lire ceci: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

30
cuongle

Vous n'avez pas besoin d'inclure vos paramètres de requête dans l'itinéraire. Il ne devrait y avoir qu'une seule carte d'itinéraire pour couvrir les méthodes Http sur tous vos ApiControllers:

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

La seule fois où vous avez besoin d'ajuster les itinéraires, c'est si vous voulez déplacer un paramètre dans le chemin réel, ce que vous ne semblez pas faire. Alors votre méthode http GET pour rechercher par deux champs serait:

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

Si vous souhaitez rechercher explicitement par un champ à la fois, vous devez penser à utiliser différents contrôleurs à des fins différentes. C'est-à-dire un SearchProductByTypeController qui a une seule méthode Get(string type). L'itinéraire serait alors/api/SearchProductByTypeController? Type = gadget

4
Nick

Êtes-vous sûr que les contrôleurs sont ok? Je veux dire, le nom des params.

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

    public string GetProductsByType(string type)
    {
        return "Requested type: " + type;
    }
0
laszlokiss88

essayez de changer string.Empty pour RouteParameter.Optional

0
hagensoft