带有多个控制器的不同区域的MVC路由

本文关键字:区域 MVC 路由 控制器 | 更新日期: 2023-09-27 18:03:50

我的解决方案结构如下:

Areas
    - Games
        -Controllers
        -Views etc
    - Movies
        -Controllers
            - MoviesController.cs
            - MovieCalendarController.cs
            - MovieSearchController.cs
        -Views etc

现在我想要的是能够做到这一点:导航到https://localhost/Movies/,点击MoviesController.cs

的索引

导航到:https://localhost/Movies/Calendar/并点击MovieCalendarController.cs的索引

最后导航到https://localhost/Movies/Search/并点击MovieSearchController.cs的索引

我尝试过但不工作(获得No route in the route table matches the supplied values.)错误:

MovieAreaRegistration.cs

public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "Movies_default",
                "Movies/{action}/{id}",
                new { controller = "Movies", action = "Index", id = UrlParameter.Optional }
            );
            context.MapRoute(
                "Calendar_default",
                "Movies/Calendar/",
                new { controller = "MovieCalendar", action = "Index", id = UrlParameter.Optional }
            );

            context.MapRoute(
                "Search_default",
                 "Movies/Search/{action}/{id}",
                    new { controller = "MovieSearch", action = "Index", id = UrlParameter.Optional }
            );
        }

抱歉,我对区域和路由不熟悉

使用属性路由后,我陷入了这个问题:

找到多个与URL匹配的控制器类型。这可以如果多个控制器上的属性路由匹配请求,则发生URL。

请求找到了以下匹配的控制器类型:MovieCalendar.UI.Areas.Movies.Controllers.MovieCalendarControllerMovieCalendar.UI.Areas.Movies.Controllers.MoviesController

<

电影控制器/strong>

[RouteArea("Movies")]
[Route("{action}")]
public class MoviesController : BaseController
{
}
<

日历控制器/strong>

[RouteArea("Movies")]
[RoutePrefix("Calendar")]
[Route("{action=Index}")]
public class MovieCalendarController : BaseController
{
}

这发生在访问url http://localhost/Movies/Calendar时,希望它会带我到MovieCalendarController索引操作方法。我可以看到为什么它会抱怨,因为在MovieController中可能有一个ActionMethod称为Calendar(没有)。

带有多个控制器的不同区域的MVC路由

您最好使用属性路由。它会让你这样做:

   public class MoviesController : Controller {
        [Route("Movies")]
        public ActionResult Index() {
            return this.View();
        }
    }
    public class MovieCalendarController : Controller {
        [Route("Movies/Calendar")]
        public ActionResult Index() {
            return this.View();
        }
    }

然后你可以摆脱你当前的路由映射并使用这个初始化你的路由:

RouteTable.Routes.MapMvcAttributeRoutes();

关于属性路由的更多信息可以在这里找到。

[RouteArea("Movies")]
[Route("{action}")]
public class MoviesController : BaseController
{
}

此路由将匹配以Movies/开头的url,后面跟着任何字符串,包括Calendar。因此,这条路由将与:

冲突
[RouteArea("Movies")]
[RoutePrefix("Calendar")]
[Route("{action=Index}")]
public class MovieCalendarController : BaseController
{
}

基于约定的路由将很难与您使用的命名约定控制器。