【问题标题】:MVC Routing issue: null entryMVC 路由问题:空条目
【发布时间】:2015-12-16 13:50:59
【问题描述】:

我有这个控制器:

public class TestController : Controller
{
    // GET: Test
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Edit(int accessLevel)
    {
        return View();
    }
}

在RouteConfig.cs中设置为:

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

routes.MapRoute(
    name: "Test Edit",
    url: "Test/Edit/{accessLevel}",
    defaults: new { controller = "Test", action = "Edit", accessLevel = UrlParameter.Optional }
);

如果我去这个网址:

http://localhost:35689/Test/Edit/2

我收到此错误:

参数字典包含参数的空条目 方法的不可为空类型“System.Int32”的“accessLevel” 'System.Web.Mvc.ActionResult Edit(Int32)' 在 'MyProject.Mvc.Client.Controllers.TestController'。一个可选的 参数必须是引用类型、可为空的类型或声明为 一个可选参数。参数名称:参数

知道这是为什么吗?我认为我使用/2 提供了正确的数据类型。

【问题讨论】:

  • 只需使用 AttributeRouting 并抛弃破烂的路由表垃圾。
  • 我实际试过了,结果还是一样,能不能提供样张?
  • 能否请您在 RouteConfig 顺序中交换您的 Route 并尝试一下
  • 你试过了吗??
  • 请在 RouteConfig 中交换您的路线,因为路线的顺序非常重要。

标签: c# asp.net-mvc


【解决方案1】:

具体的路由定义应该在通用默认路由之前定义。路由定义的顺序很重要

routes.MapRoute(
    name: "Test Edit",
    url: "Test/Edit/{accessLevel}",
    defaults: new { controller = "Test", action = "Edit", 
                                                    accessLevel = UrlParameter.Optional }
);

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

如果你像你所拥有的那样保持其他顺序(通用默认优先,稍后特定),当请求到达 Test/Edit/2 时,它将与通用路由定义匹配,因为Test 是一个有效的控制器并且Edit 是有效的操作方法名称,2 可能是 Id 参数的有效参数值。 由于请求获得了与其 url 模式匹配的有效路由定义,因此永远不会根据第一个下面定义的其他路由定义对其进行评估。

首先保留所有特定的路由定义,并将generic-default 作为最后一个。

或者你可以在Test控制器中使用属性路由来定义这个路由模式。要启用属性路由,你可以在RouteConfig.cs的RegisterRoutes方法中调用MapMvcAttributeRoutes方法。您仍将保留默认路由定义。

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

    routes.MapMvcAttributeRoutes();

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

    );
}

在你的TestController

[Route("Test/Edit/{id?}")]
public ActionResult Edit(int? id)
{
   //check id value  and return something
}

此外,如果自定义路由与通用默认路由定义匹配,则定义自定义路由毫无意义。在您的情况下,即使您没有定义自定义路由,Test/Edit/2 也会转到TestControllerEdit 操作方法,因为请求与默认路由定义匹配。

人们通常使用这些自定义路由定义来创建漂亮的 url 模式,例如

[Route("Product/{id}/{name}")]
public ActionResult View(int id,string name)
{
   //check id value  and return something
}

此路由定义将匹配请求Product/34/seo-friendly-name。看看这个问题的网址,你就会明白我在这里解释的内容。

【讨论】:

    【解决方案2】:

    在 RoutesConfig.cs 中切换路由。它们应该从最具体到一般。

    您的默认路线正在赶上这条路线。

    【讨论】:

      【解决方案3】:

      请在 RouteConfig 中交换您的路线,因为路线的顺序非常重要。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-29
        • 2011-07-31
        • 1970-01-01
        相关资源
        最近更新 更多