【问题标题】:How to convert query string parameters to route in asp.net mvc 4如何在asp.net mvc 4中将查询字符串参数转换为路由
【发布时间】:2014-02-11 17:45:30
【问题描述】:

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

我需要的路由是 /blogs/student/firstname-lastname 所以 /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。任何有关如何解决此问题的建议将不胜感激。

我的路由配置

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

【问题讨论】:

  • 实际上匹配哪条路线?您只向我们展示了一个您的映射路线。
  • 在尝试 /blogs/student/firstname-lastname 时会抛出 404,但如果我使用 /blogs/student/?name=firstname-lastname 它会解析 /blogs/student/ 控制器的索引操作,它有一个字符串参数名称。

标签: c# asp.net asp.net-mvc asp.net-mvc-4 routes


【解决方案1】:

您必须在默认路由之前声明自定义路由。否则它将映射到 {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 的区域模式匹配,这将导致 404。将您的自定义路由添加到默认路由上方的 BlogsAreaRegistration.cs 文件中。

【讨论】:

  • 我有,请看我添加的RouteConfig
  • 通常区域路线在您的其他路线之前创建。如果您确实创建了一个名为 blogs 的区域,那么您的区域中可能存在一个 BlogsAreaRegistration.cs 文件,该文件之前的路由冲突。您是否有理由没有在 BlogsAreaRegistration.cs 文件中创建此路由?
【解决方案2】:

尝试为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,这会带来无法匹配路由的额外好处。

编辑:

如果您有同名的控制器.. 您需要在每个区域的 both 路由中包含命名空间。控制器在哪里并不重要……即使在不同的区域。

尝试为每个处理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 用于管理区域中的那个。

【讨论】:

  • 有道理,但仍然抛出 404。
  • 您是否在另一个区域有另一个名为Student 的控制器?
  • 我在管理区做,但我已将 area="Blogs" 添加到路由默认值,它仍然是 404。
  • 如果我将路由添加到 Global.ascx 而不是 RouteConfig,我会得到 The view 'Index' or its master was not found or no view engine support the searched locations。搜索了以下位置:~/Views/Student/Index.aspx ~/Views/Student/Index.ascx ~/Views/Shared/Index.aspx ~/Views/Shared/Index.ascx ~/Views/Student/Index。 cshtml ~/Views/Student/Index.vbhtml ~/Views/Shared/Index.cshtml ~/Views/Shared/Index.vbhtml 它没有在该区域寻找视图。
  • 我已经更新了我的答案。尝试将命名空间显式传递给 both 涉及Student 控制器的路由。
【解决方案3】:

尝试将参数添加到路由中:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2014-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多