0

我正在为用户、管理员、商店、论坛等创建区域

在每个区域中,它都有自己的 Controllers、Models、Views 文件夹。在根模型、根控制器和根视图中,我在其中共享了组件。

结构A:

Root/ -> Models/, Controllers/, Views/
Root/User/ -> Models/, Controllers/, Views/
Root/Admin/ -> Models/, Controllers/, Views/
Root/Shop/ -> Models/, Controllers/, Views/
Root/Forum/ -> Models/, Controllers/, Views/

我可能错了,但他们真的不认为我在每个业务逻辑组中重复 MV 和 C 文件夹。我在想一个更好的结构是使用 MV 和 C 作为主要文件夹并在其中布局我的业务逻辑组:

结构 B:

Root/Views/ -> User/, Admin/, Shop/, Forum/ ...etc
Root/Models/ -> User/, Admin/, Shop/, Forum/ ...etc
Root/Controllers/ -> User/, Admin/, Shop/, Forum/ ...etc

但是,如果我确实以这种方式构建文件夹,我就失去了划分网站逻辑功能的区域(或从用户的角度来看,子文件夹路径)的能力。

例如

使用结构A,我可以:

www.mywebsite.com/Users(area)/Account(controller)/LogOn(action)
www.mywebsite.com/Admin(area)/Account(controller)/LogOn(action) 

请注意,我可以在不同的区域使用相同的控制器和操作名称。

使用结构 B,我能做的最好的事情是:

www.mywebsite.com/AdminAccount(controller)/LogOn(action)
www.mywebsite.com/UserAccount(controller)/LogOn(action)

无法实现无区域的单字子文件夹效果。如果不仅如此,这里的控制器名称很快就会变得更长更混乱。更不用说您在同一个 controller.cs 文件中堆叠了大量的操作。

所以,无论如何,我的观点是,如果我发现结构 B 对我更有意义,我该如何配置路由来实现这一点?

4

1 回答 1

1

所以你想要结构 B 的 url 对应于 A?

您将放弃约定优于配置。

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "UserAccount", // Route name
            "users/account/{action}/{id}", // URL with parameters
            new { controller = "UserAccount", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
    }

另一种选择是编写自定义路由处理程序并引入您自己的约定。类似于以下内容(新约定是将用户和帐户连接起来以获取 www.mywebsite.com/Users/Account/LogOn 中的 UsersAccountController)。我没有测试看看它如何处理区域,但如果你有问题让我知道,我可以看看。

public class CustomConventionRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
    {
        string controller = requestContext.RouteData.Values["controller"].ToString();

        object controllerModifier;
        if (requestContext.RouteData.Values.TryGetValue("controllerModifier", out controllerModifier))
        {
            requestContext.RouteData.Values["controller"] = string.Concat(controllerModifier, controller);
        }

        return base.GetHttpHandler(requestContext);
    }
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(
        new Route(
            "{controllerModifier}/{controller}/{action}",
            new RouteValueDictionary(new { controllerModifier = UrlParameter.Optional, controller = "Home", action = "Index" }),  //defaults
            new CustomConventionRouteHandler()));
}
于 2012-07-07T07:48:38.947 回答