发布到控制器会出现 404 错误 - 路由似乎已损坏?

Posting to controller gives 404 error - routing seems to be broken?

我有一个非常简单的控制器 + 操作,当我执行 POST 时得到 404,我根本不明白。

我的路由配置:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


    routes.MapRoute(
                name: "Task view",
                url: "task/{projectid}",
                defaults: new { controller = "Task", action = "Index" });

    routes.MapRoute(
               name: "Default",
               url: "{controller}/{action}/{id}",
               defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

}

我的控制器:

public class TaskController : Controller
{


    // GET: Task
    [System.Web.Mvc.HttpGet]
    public async Task<ActionResult> Index(int projectid)
    {
       // extremely nice and insightful code
        return View(vm);
    }

    [System.Web.Mvc.HttpPost]
    public async Task<JsonResult> UpdateSigneeRequest([FromBody] TaskViewModel task)
    {
        // even more smart code
        return Json("OK", JsonRequestBehavior.AllowGet);
    }

}

现在,我可以轻松打开 /task/75 并获得正确的索引结果和项目 ID。但我根本无法 POST 到 /task/UpdateSigneeRequest 。我也试过从这个方法中删除参数,但似乎没有任何效果。

我根本不明白这一点,因为我的 Default 路由应该与此匹配(控制器是任务,操作是 UpdateSigneeRequest,id 是可选的)。

您可以为您的路由定义提供约束,使其特定于 url 中 task 和您的 GET 请求中的 number 值将根据该定义正确处理(例如:/task/100)。

routes.MapRoute(
    "Task view",
    url: "task/{projectid}",
    defaults: new { controller = "Task", action = "Index" },
    constraints: new { projectid = @"\d+" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

您也可以在 attribute routing 中执行相同的操作(为您的参数指定约束)。

[System.Web.Mvc.Route("Task/{projectid:int}")]
public async Task<ActionResult> Index(int projectid)
{
     return View(new SomeViewModel { ProjectId =  projectid});
}
[System.Web.Mvc.HttpPost]
public async Task<JsonResult> UpdateSigneeRequest(IndexVm task)
{
    return Json("OK", JsonRequestBehavior.AllowGet);
}