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

Tho*_*que 1 c# asp.net-mvc routes

我有一个名为的控制器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);
    }
Run Code Online (Sandbox Code Playgroud)

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

我尝试在我的应用程序的RegisterRoutes方法中添加新路由,但我找不到获得所需结果的方法...

谁能告诉我如何实现这一目标?

注意:这实际上与这个问题非常相似,但没有接受答案,而且最高的投票答案对我来说没有任何意义,因为我对MVC完全不熟悉......

Sco*_*son 9

将参数名称更改yearid,这将匹配MVC添加到项目的默认路由.

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

routes.MapRoute(
    "default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }
);
Run Code Online (Sandbox Code Playgroud)

在这条路线,你可以看到,是为了具体命名的三个令牌controller,action以及其传递给行动是第三代币id.当请求进入您的应用程序时,ASP.NET MVC将分析当前映射的路由,并尝试通过对您的控制器使用反射来查找与它们匹配的方法签名.

当它查看你的Movie控制器时,它会看到一个被调用的动作ByYear,但是该方法接受一个被调用的整数year,而不是id.这就是为什么你最终会遇到像为特定Action /Movie/ByYear?year={year}创建一样的东西ActionLink.所以要解决这个问题,你有两个选择:

解决此问题的第一个也是最简单的方法是只更改Action的方法签名以接受名为的参数id,这是我上面推荐的.这样可以正常工作,但是当我稍后回到那个源并且想知道为什么调用该参数时,我可以看到它可能会引起一些混乱id.

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

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

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

编辑2:另外需要注意的是路由引擎将在它找到的匹配您的请求的第一条路线上停止,因此任何这样的自定义路线都应该在默认路线之前添加,这样您就可以确定它们会被找到.