如何将查询字符串参数转换为asp.net mvc 4中的路由

我有一个我正在构建的博客系统,我似乎无法让ASP.NET MVC了解我的路线。

我需要的路线是/ blogs / student / firstname-lastname so / blogs / student / john-doe,它们路由到博客区域,学生控制器的索引操作,它采用字符串名称参数。

这是我的路线

routes.MapRoute( name: "StudentBlogs", url: "blogs/student/{name}", defaults: new { controller = "Student", action="Index"} ); 

我的控制器动作

 public ActionResult Index(string name) { string[] nameparts = name.Split(new char[]{'-'}); string firstName = nameparts[0]; string lastName = nameparts[1]; if (nameparts.Length == 2 && name != null) { // load students blog from database } return RedirectToAction("Index", "Index", new { area = "Blogs" }); } 

但它似乎无法解决…它与/ blogs / student /?name = firstname-lastname一起使用,但不使用我想要的路径,即/ blogs / student / firstname-lastname。 任何关于如何解决这个问题的建议将不胜感激。

我的RouteConfig

  public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "StudentBlogs", url: "blogs/student/{name}", defaults: new { controller = "Student", action = "Index"}, constraints: new { name = @"[a-zA-Z-]+" }, namespaces: new string[] { "IAUCollege.Areas.Blogs.Controllers" } ); routes.MapRoute( name: "Sitemap", url :"sitemap.xml", defaults: new { controller = "XmlSiteMap", action = "Index", page = 0} ); //CmsRoute is moved to Gloabal.asax // campus maps route routes.MapRoute( name: "CampusMaps", url: "locations/campusmaps", defaults: new { controller = "CampusMaps", action = "Index", id = UrlParameter.Optional } ); // core route routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); // error routes routes.MapRoute( name: "Error", url: "Error/{status}", defaults: new { controller = "Error", action = "Error404", status = UrlParameter.Optional } ); // Add our route registration for MvcSiteMapProvider sitemaps MvcSiteMapProvider.Web.Mvc.XmlSiteMapController.RegisterRoutes(routes); } } 

您必须在默认路由之前声明自定义路由。 否则它将映射到{controller} / {action} / {id}。


Global.asax通常如下所示:

 protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); } 

如果您创建了一个名为Blogs的区域,则会有相应的BlogsAreaRegistration.cs文件,如下所示:

 public class BlogsAreaRegistration : AreaRegistration { public override string AreaName { get { return "Blogs"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Admin_default", "Blogs/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); } } 

连字符有时被视为路线中的正斜杠。 当您使用路线blogs/students/john-doe ,我的猜测是它使用blogs/students/john/doe匹配上面的Area模式,这将产生404.将您的自定义路由添加到BlogsAreaRegistration.cs文件位于默认路由之上。

尝试将参数添加到路线:

 routes.MapRoute( name: "StudentBlogs", url: "blogs/student/{name}", defaults: new { controller = "Student", action="Index", name = UrlParameter.Optional} ); 

尝试为name参数添加约束:

 routes.MapRoute( name: "StudentBlogs", url: "blogs/student/{name}", defaults: new { controller = "Student", action="Index" }, constraints: new { name = @"[a-zA-Z-]+" } ); 

在MVC中,破折号有点奇怪..因为它们用于解析下划线。 如果这不起作用我会删除这个答案(虽然它应该)。

如果使用诸如/blogs/student/12387类的URL,则具有无法匹配路由的额外好处。

编辑:

如果您具有相同名称的控制器,则需要在每个区域的两个路由中包含命名空间。 控制器在哪里都没关系..即使在不同的区域。

尝试将相应的命名空间添加到处理Student控制器的每个路由中。 有点像这样:

 routes.MapRoute( name: "StudentBlogs", url: "blogs/student/{name}", defaults: new { controller = "Student", action="Index" }, namespaces: new string[] { "Website.Areas.Blogs.Controllers" } ); 

..或者也许是Website.Areas.Admin.Controllers用于管理区域中的那个。