Как направить запросы GET и DELETE по одному и тому же URL на разные методы контроллера
Вот мои маршруты в Global.asax
routes.MapRoute("PizzaGet", "pizza/{pizzaKey}", new { controller = "Pizza", action = "GetPizzaById" });
routes.MapRoute("DeletePizza", "pizza/{pizzaKey}", new { controller = "Pizza", action = "DeletePizza" });
Вот мои методы контроллера
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetPizzaById(long pizzaKey)
[AcceptVerbs(HttpVerbs.Delete)]
public ActionResult DeletePizza(long pizzaKey)
Когда я делаю GET, он возвращает объект, но когда я делаю DELETE, я получаю 404. Кажется, что это должно работать, но это не так.
Если я переключу два маршрута вокруг, тогда я смогу УДАЛИТЬ, но получу 404 на GET.
Теперь это действительно красиво. Спасибо
routes.MapRoute("Pizza-GET","pizza/{pizzaKey}",
new { controller = "Pizza", action = "GetPizza"},
new { httpMethod = new HttpMethodConstraint(new string[]{"GET"})});
routes.MapRoute("Pizza-UPDATE", "pizza/{pizzaKey}",
new { controller = "Pizza", action = "UpdatePizza" },
new { httpMethod = new HttpMethodConstraint(new string[] { "PUT" }) });
routes.MapRoute("Pizza-DELETE", "pizza/{pizzaKey}",
new { controller = "Pizza", action = "DeletePizza" },
new { httpMethod = new HttpMethodConstraint(new string[] { "DELETE" }) });
routes.MapRoute("Pizza-ADD", "pizza/",
new { controller = "Pizza", action = "AddPizza" },
new { httpMethod = new HttpMethodConstraint(new string[] { "POST" }) });
3 ответа
Решение
Вы можете ограничить свои маршруты с помощью HTTP-глагола следующим образом:
string[] allowedMethods = { "GET", "POST" };
var methodConstraints = new HttpMethodConstraint(allowedMethods);
Route reportRoute = new Route("pizza/{pizzaKey}", new MvcRouteHandler());
reportRoute.Constraints = new RouteValueDictionary { { "httpMethod", methodConstraints } };
routes.Add(reportRoute);
Теперь вы можете иметь оба маршрута, и они будут ограничены глаголами.
[ActionName("Pizza"), HttpPost]
public ActionResult Pizza_Post(int theParameter) { }
[ActionName("Pizza"), HttpGet]
public ActionResult Pizza_Get(int theParameter) { }
[ActionName("Pizza"), HttpHut]
public ActionResult Pizza_Hut(int theParameter) { }
Решение Womp не работает для меня.
Это делает:
namespace ...
{
public class ... : ...
{
public override void ...(...)
{
context.MapRoute(
"forSpecificRequestMethod",
"...{rctrl}/{ract}/{id}",
new { controller = "controller", action = "action", id = UrlParameter.Optional },
new RouteValueDictionary(new { httpMethod = new MethodRouteConstraint("REQUEST_VERB_HERE") }),
new[] { "namespace" }
);
context.MapRoute(
"default",
"...{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "namespace" }
);
}
}
internal class MethodRouteConstraint : IRouteConstraint
{
protected string method;
public MethodRouteConstraint(string method)
{
this.method = method;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return httpContext.Request.HttpMethod == method;
}
}
}
В случае, если у кого-то еще есть проблемы с разными маршрутами в зависимости от метода запроса.