当前位置:  开发笔记 > 编程语言 > 正文

MVC路由问题:空条目

如何解决《MVC路由问题:空条目》经验,为你挑选了1个好方法。

我有这个控制器:

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'的空条目,用于'MyProject.Mvc.Client.Controllers.TestController'中的方法'System.Web.Mvc.ActionResult Edit(Int32)'.可选参数必须是引用类型,可空类型,或者声明为可选参数.参数名称:参数

知道为什么会这样吗?我认为我正在提供正确的数据类型/2.



1> Shyju..:

应在通用默认路由定义之前定义特定路由定义.路线定义的顺序非常重要.

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 }
);

如果您保留其他顺序(如首先是Generic-default,后面是特定的顺序),当请求到来时Test/Edit/2它将与通用路由定义匹配,因为它Test是一个有效的控制器并且Edit是一个有效的操作方法名称,2可能是Id param的有效参数值.由于请求获得了与其url模式匹配的有效路由定义,因此永远不会根据第一个定义的其他路由定义来评估它.

保留所有特定的路径定义,并将generic-default其作为最后一个.

或者您可以使用属性路由在Test控制器中定义此路由模式.要启用属性路由,可以MapMvcAttributeRoutesRegisterRoutesRouteConfig.cs 方法中调用该方法.您仍将保留默认路由定义.

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也将转到Edit操作方法,TestController因为请求与默认路由定义匹配.

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

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

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

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有