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

Маршрутизация на основе имени параметра строки запроса

Я пытаюсь настроить маршрутизацию в проекте MVAP4 WebAPI.

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

/api/products?name=WidgetX - возвращает все продукты с именем WidgetX /api/products?type=gadget - возвращает все продукты гаджета типа

Маршруты настроены следующим образом:

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

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

4b9b3361

Ответ 1

Вам нужен только один маршрут ниже, потому что строка запроса не используется в качестве параметров маршрутизации:

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

И затем определите два метода, как показано ниже:

GetProductsByName(string name)
{}

GetProductsByType(string type)
{}

Механизм маршрутизации достаточно умен, чтобы направить URL-адрес на правильное действие, основанное на имени строки запроса, независимо от того, совпадают ли параметры ввода. Конечно, при всех методах с префиксом Get

Вам может потребоваться прочитать следующее: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

Ответ 2

Вам не нужно включать параметры запроса в маршрут. Должна быть только одна простая карта маршрута для покрытия Http-методов на всех ваших ApiControllers:

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

Единственный раз, когда вам нужно настроить маршруты, нужно, если вы хотите переместить параметр в фактический путь, который вы, кажется, не делаете. Тогда ваш метод GET http для поиска по двум полям будет выглядеть следующим образом:

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

Если вы хотите явно искать по одному полю за раз, вам следует подумать об использовании разных контроллеров для разных целей. То есть, a SearchProductByTypeController, который имеет единственный метод Get(string type). Тогда маршрут будет /api/SearchProductByTypeController? Type = gadget

Ответ 3

попробуйте изменить string.Empty для RouteParameter.Optional

Ответ 4

Вы уверены, что контроллеры в порядке? Я имею в виду, имя params.

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

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