我有这个控制器:
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
.
应在通用默认路由定义之前定义特定路由定义.路线定义的顺序非常重要.
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控制器中定义此路由模式.要启用属性路由,可以MapMvcAttributeRoutes
在RegisterRoutes
RouteConfig.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,你就会明白我在这里解释的内容.