.net - 与另一个路由匹配的路由,忽略 HttpMethodConstraint?

标签 .net asp.net-mvc asp.net-mvc-3 routing asp.net-mvc-routing

我有一个 ASP.net MVC 3 站点,其路由如下:

routes.MapRoute("Get", "endpoint/{id}",
    new { Controller = "Foo", action = "GetFoo" },
    new { httpMethod = new HttpMethodConstraint("GET") });

routes.MapRoute("Post", "endpoint/{id}",
    new { Controller = "Foo", action = "NewFoo" },
    new { httpMethod = new HttpMethodConstraint("POST") });

routes.MapRoute("BadFoo", "endpoint/{id}",
    new { Controller = "Error", action = "MethodNotAllowed" });

routes.MapRoute("NotFound", "", 
    new { controller = "Error", action = "NotFound" });

因此,简而言之,我有一个与某些 HTTP 动词(如 GET 和 POST)匹配的路由,但在其他 HTTP 动词(如 PUT 和 DELETE)上它应该返回一个特定的错误。

我的默认路由是 404。

如果我删除“BadFoo”路由,那么针对端点/{id} 的 PUT 将返回 404,因为没有其他路由匹配,所以它转到我的 NotFound 路由。

问题是,我有很多像 Get 和 Post 这样的路由,我有一个 HttpMethodConstraint,我必须创建一个像 BadFoo 路由这样的路由,只是为了在路由字符串上而不是在 Method 上找到正确的匹配,这很糟糕不必要地增加我的路由。

如何仅使用 Get、Post 和 NotFound 路由设置路由,同时仍然区分未找到 HTTP 404(=无效 URL)和不允许 HTTP 405 方法(=有效 URL,错误 HTTP 方法)?

最佳答案

您可以使用自定义 ControllerActionInvoker 将 HTTP 方法验证委托(delegate)给 MVC 运行时,而不是使用路由约束。和 ActionMethodSelector [HttpGet] 等属性, [HttpPost] , ETC。:

using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication6.Controllers {

   public class HomeController : Controller {

      protected override IActionInvoker CreateActionInvoker() {
         return new CustomActionInvoker();
      }

      [HttpGet]
      public ActionResult Index() {
         return Content("GET");
      }

      [HttpPost]
      public ActionResult Index(string foo) {
         return Content("POST");
      }
   }

   class CustomActionInvoker : ControllerActionInvoker {

      protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) {

         // Find action, use selector attributes
         var action = base.FindAction(controllerContext, controllerDescriptor, actionName);

         if (action == null) {

            // Find action, ignore selector attributes
            var action2 = controllerDescriptor
               .GetCanonicalActions()
               .FirstOrDefault(a => a.ActionName.Equals(actionName, StringComparison.OrdinalIgnoreCase));

            if (action2 != null) {
               // Action found, Method Not Allowed ?
               throw new HttpException(405, "Method Not Allowed");
            }
         }

         return action;
      }
   }
}

请注意我的最后一条评论“找到的操作,不允许的方法?”,我将其写为一个问题,因为可以有 ActionMethodSelector与 HTTP 方法验证无关的属性...

关于.net - 与另一个路由匹配的路由,忽略 HttpMethodConstraint?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5160860/

相关文章:

c# - 当 T 正在实现类时,C++/CLI 中的 IComparable<T>

asp.net-mvc - ASP.NET MVC 4 - 允许 URL 中的破折号/连字符

asp.net-mvc - Glass.Mapper 是否支持指向 Sitecore 7 中的 MVC 模型的链接?

ajax - MVC3 Razor Ajax表单提交

.net - 如何根据 Controller 使用 .NET MVC3 Framework 读取 App_Data 中的 xml 文件?

c# - .NET 1.1 中未处理的异常处理程序

c# - 如何遍历 C# 中的所有枚举值?

.net - WPF 的 Windows 7 主题?

css - MVC3 TextBoxFor 添加类移除input-validation-error验证css类

jquery - Hook 成功事件 MVC 验证(每个字段)