Параметры Web.API MapHttpRoute - программирование
Подтвердить что ты не робот

Параметры Web.API MapHttpRoute

У меня проблемы с моей маршрутизацией Web.API. У меня есть следующие два маршрута:

config.Routes.MapHttpRoute(
    name: "MethodOne",
    routeTemplate: "api/{controller}/{action}/{id}/{type}",
    defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional }
);

config.Routes.MapHttpRoute(
    name: "MethodTwo",
    routeTemplate: "api/{controller}/{action}/{directory}/{report}",
    defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional }
);

И в моем контроллере эти два метода:

[HttpGet]
[ActionName("methodone")]
public string MethodOne(string id, string type)
{
    return string.Empty;
}

[HttpGet]
[ActionName("methodtwo")]
public string MethodTwo(string directory, string report)
{
    return string.Empty;
}

Эти два, казалось бы, не могут жить бок о бок. Если я прокомментирую маршрут MethodOne в WebApiConfig, работает метод MethodTwo. Метод Commenting MethodTwo позволяет MethodOne работать. Оставляя как uncommented, MethodOne работает, но не MethodTwo.

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

Я действительно скучаю по WebGet(UriTemplate="") из отдыха WCF.

У меня есть один контроллер, который имеет много методов, некоторые с 1, 2, 3 или даже больше параметров. Я не могу поверить, что не могу использовать значащие имена параметров с помощью подхода MapHttpRoute.

Я могу полностью прокомментировать это и использовать WebGet()... но до того, как я добрался туда, мне захотелось узнать, не хватает ли чего-то.

4b9b3361

Ответ 1

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

Таким образом, ваш первый маршрут будет с удовольствием соответствовать обоим запросам следующим образом.

~/methodone/1/mytype => action = methodone, id = 1, and type = mytype
~/methodtwo/directory/report => action = methodtwo, id = directory, and type = report

Чтобы обойти это, вы должны использовать маршрут, например

config.Routes.MapHttpRoute(
    name: "MethodOne",
    routeTemplate: "api/{controller}/methodone/{id}/{type}",
    defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional }
);

config.Routes.MapHttpRoute(
    name: "MethodTwo",
    routeTemplate: "api/{controller}/methodtwo/{directory}/{report}",
    defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional }
);

Даже если вы используете WebGet, вам, возможно, придется сделать что-то похожее на двусмысленные те два метода, которые я считаю.

Ответ 2

Вы можете передать параметры в строке запроса, например /MethodTwo? directory = a & report = b, но если вы хотите, чтобы они отображались в пути, это выглядит хорошим кандидатом для маршрутизации на основе атрибутов, Здесь у Филиппа есть отличная статья:

http://www.strathweb.com/2012/05/attribute-based-routing-in-asp-net-web-api/

Ответ 3

Из http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

Вы также можете предоставить ограничения, которые ограничивают использование сегмента URI сопоставить местозаполнитель:

: new {id = @ "\ d +" }//Только совпадения, если "id" - один или   больше цифр.

Добавление этого ограничения в "MethodOne" (api/{controller}/{action}/{id}/{type}) будет означать, что числа будут соответствовать только, если {id} - это число, в противном случае оно будет соответствовать методу MethodTwo, ( "апи/{контроллер}/{действие}/{каталог}/{} отчет" ).