代码之家  ›  专栏  ›  技术社区  ›  Thomas Levesque

如何在ASP.NET MVC中定义此路由?

  •  1
  • Thomas Levesque  · 技术社区  · 15 年前

    我有一个叫 Movie ,其操作名为 ByYear ,以年为参数:

        public ActionResult ByYear(int year)
        {
            ViewData["Title"] = string.Format("Movies released in {0}", year);
            var repository = MvcApplication.GetRepository();
            var movies = repository.Medias
                                    .OfType<Movie>()
                                    .Where(m => m.Year == year);
            return View("Index", movies);
        }
    

    我想使用以下URL访问此操作: /电影/拜年/年 ,但此操作的唯一有效路由是: 电影/ ByYear?年= {年} .

    我尝试在我的应用程序中添加新路由 RegisterRoutes 方法,但我找不到一种方法来获得想要的结果…

    有人能告诉我如何做到这一点吗?

    注:这实际上非常类似于 this question 但没有人接受答案,最高投票的答案对我来说毫无意义,因为我对MVC完全陌生……

    3 回复  |  直到 15 年前
        1
  •  9
  •   Scott Arrington    15 年前

    更改参数的名称 year id 这将匹配MVC添加到项目中的默认路由。

    因此,为了进一步说明,让我们来看一下由ASP.NET MVC添加的默认路由:

    routes.MapRoute(
        "default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = "" }
    );
    

    在这个路由中,您可以看到三个专门为 controller , action ,传递给操作的第三个令牌是 身份证件 . 当请求进入应用程序时,ASP.NET MVC将分析当前映射的路由,并尝试通过对控制器使用反射来查找与之匹配的方法签名。

    当它看着你 Movie 控制器,它看到一个名为 ByYear 但是,该方法接受一个名为 不是 身份证件 . 这就是为什么你最终会得到 /Movie/ByYear?year={year} 当你创建一个 ActionLink 为了那个特别的行动。为了解决这个问题,您有两个选择:

    解决此问题的第一个也是最简单的方法是更改操作的方法签名以接受名为 身份证件 这是我上面推荐的。这将很好地工作,但我可以看到,当您稍后返回到该源时,它可能会在哪里引起一点混乱,并想知道为什么您调用该参数 身份证件 .

    第二个方法是添加另一个与该方法签名匹配的路由。为此,您应该打开global.asax并添加以下内容(未测试,但应该有效):

    routes.MapRoute(
        "MoviesByYear",
        "Movies/ByYear/{year}",
        new { controller = "Movie", action = "ByYear" }
    );
    

    这个路由是硬编码的,是的,但是它不会破坏系统中的其他路由,并且它允许您调用方法参数 .

    编辑2:另一个需要注意的是,路由引擎将在它发现的与您的请求匹配的第一个路由上停止,因此应该添加像这样的任何自定义路由。 之前 默认路由,以便您确定将找到它们。

        2
  •  4
  •   Thomas Levesque    15 年前

    好吧,我刚知道怎么做。我只需要创建新的路线 之前 默认路由…我认为这个命令没有任何意义

            routes.MapRoute(
                "MovieByYear",                                          // Route name
                "Movie/ByYear/{year}",                                  // URL with parameters
                new { controller = "Movie", action = "ByYear" }         // Parameter defaults
            );
    

    编辑:有没有更简单的方法?(不涉及重命名参数)。我想做点类似的事情:

    [Route("/Movie/ByYear/{year}")]
    public ActionResult ByYear(int year)
    {
        ...
    
        3
  •  2
  •   Bob Palmer    15 年前

    撇开设计考虑因素不谈,如果不想重命名参数,可以添加类似下面的路由的内容,这强制使用year参数

    routes.MapRoute(
         "MovieByYear",                        // Route name
         "Movie/ByYear/{year}",       // URL with parameters
         new { controller = "Movie", action = "ByYear" },
         new { year = @"\d+" }                 // Parameter defaults
    );