我确信我做错了什么,但是花了几个小时就没有运气,如果有人可以帮我解决这个问题,我会很高兴。
似乎路由系统仅在第一次路由注册中表示参数。
这就是我的global.asax.cs的样子
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication4
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"t", // Route name
"{controller}/{action}/{i}/{v}",
new { i = UrlParameter.Optional, v = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { id = UrlParameter.Optional }
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
}
这就是家庭控制器的样子
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication4.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(int? id)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About(int? a)
{
return View();
}
}
}
问题是当我尝试这个网址时
http://localhost:52230/Home/Index/2
id始终为null。但是,如果我尝试
http://localhost:52230/Home/Index?id=2
....它有效。
如果我在任何其他路线之前注册home / index,它也有效。在这种情况下,稍后注册的路线在接受参数时会遇到同样的问题。
我在这里做错了什么?
更新
我希望这两个控制器都能正常工作,我的路线注册怎么样?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication4.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(int? id)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
}
}
第二个控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication4.Controllers
{
public class VisitorController : Controller
{
//
// GET: /VisitorSecurityPoints/
public ActionResult Test(string i,string v)
{
return View();
}
}
}
答案 0 :(得分:2)
路线按特定顺序排列。这意味着当查看已请求的URL时,MVC将始终尝试匹配最具体的路由。路线列表中的路线将越来越“贪婪”。
如果我们仔细研究一下有问题的两条路线,我们可以看到除非提供v
参数,否则MVC无法区分这两条路线。它们都具有controller
和action
参数,并且它们都具有可选的第三个参数。如果没有提供v
,MVC将无法知道使用哪条路由,除非这样的优先级系统到位,这就是为什么路由表中路由的顺序很重要。
有一些方法可以让MVC区分这样的两条路由,但这取决于相关参数的数据类型。例如,如果i
是DateTime
而不是int
,则可以添加仅与日期匹配的Route Constraint。有关约束的更多信息,请参阅this文章。
我也是理查德关于使用RouteDebugger的建议。它对于帮助理解诸如此类的情况非常有用,并且可以实现更清晰的路由表设计。
我还应该提一下,当你在末尾标记?id=2
时,URL“工作”的原因是因为MVC尝试将绑定模型直接建模到查询字符串中的匹配操作参数。但是,请注意,匹配路由的参数将优先于查询字符串中提供的值。例如,使用以下路线:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
导航至http://localhost:50754/home/index/2
将导致id
为2
导航至http://localhost:50754/home/index/?id=4
将导致id
为4
导航至http://localhost:50754/home/index/2?id=4
将导致id
为2.
解决特定问题的最简单方法是更改路由表以包含以下路由:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"visitors", // Route name
"visitor/{action}/{i}/{v}", // URL with parameters
new
{
controller = "Visitor", action = "Test",
i = UrlParameter.Optional, v = UrlParameter.Optional
}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
请注意,此新路由中仍存在{action}
参数。这样可以更容易地扩展它以满足控制器中的其他操作。如果需要将路径约束到控制器上存在的操作,则需要添加前面提到的路径约束。
这种方法的一个警告是,如果您经常指定新路由以匹配几个URL,则路由表可以非常快速地增长。这可能会因为现有路由而更难以向站点添加新功能,并且还可能使维护更加困难。只要有可能,您应该尝试设计一个匹配默认{controller}/{action}/{id}
路由的路由,因为从长远来看,它使维护和调试变得更加容易。
答案 1 :(得分:1)
我相信它是因为你的其他路线(“t”)首先匹配。
答案 2 :(得分:0)
您可以使用RouteDebugger检查匹配的路线。只需使用nuget安装它:
PM> install-package RouteDebugger
当您查看该页面时,它将列出您的所有路线并指出哪些路线匹配。将使用第一个匹配的路线。