2

我如何以及在哪里配置我的应用程序,以便在它启动时,操作(因此要显示的页面)不在根结构中,而是在我选择的给定区域中?

假设,Action =“ IndexOfArticles ”,Controller =“ Articles ”,Area =“ News ”。我希望在启动应用程序时将此设置设为默认设置。

我研究过NewsAreaRegistration类并设置了上述配置。现在我怀疑,为了让它工作,我还需要对 Global.asx.cs 做一些事情,但我不知道该怎么做。

编辑

这就是我的意思

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

例如,上面的代码将导致应用程序以位于Home控制器中的Index动作开始执行。那不是我想要的。感谢您的帮助。

4

2 回答 2

3

考虑到你一直在问的问题的性质,我想推荐一个我认为你会真正喜欢的资源。Steven Sanderson 的书“Pro ASP.NET MVC 2 Framework(第二版)”由 apress 出版。第 8 章特别详细介绍了路由和区域。这本书本身很棒而且很透彻。我读过的最好的开发/编程书籍之一。它以 Kindle 形式提供,如果您直接从 apress 订购,则可以 PDF 电子书形式获得。当然也有纸质版本:

亚马逊链接

或者

直接来自 Apress

您可能想了解的关于区域的具体事情是它们基于名称空间。当您创建一个区域时,该区域的名称空间是 MVC 如何定位它们并决定什么是“在”和什么不是区域。通常,这意味着路由到区域是通过将区域名称作为 URL 中的第一个文件夹的 URL 完成的,但这会映射到控制器的命名空间,不一定是物理文件夹名称(尽管如果您想保留您的理智)。

Manaf 示例中的路线是“偶然”而不是有意地工作的,这可能就是为什么你没有完全理解它的作用。在“根区域”(即不在区域中的控制器文件夹)中有一个控制器名称不明确的怪癖。对于一条通往根区域的路由,但它在那里找不到控制器,它会扫描所有区域以寻找匹配项。在这种情况下,它会在您的新闻命名空间中找到匹配项,并且可以正常工作。但这种扫描只有在只有一个匹配的控制器时才有效。因此,如果您要在另一个区域中创建另一个具有相同名称的控制器,它将失败并出现“找到多种类型”的异常。

您有两种好方法可以使这项工作更可靠。通过在路由中优先考虑新闻区域,或者通过重定向:

重定向:

您可以将浏览器重定向到您希望它们开始的区域的 URL,而不是将根请求路由到特定区域中的控制器。因此,它们从“yoursite.com/”开始,并将被重定向到“yoursite.com/news/articles”URL。为此,您需要创建一个根级控制器并使用默认路由。因此,在根控制器文件夹(而不是区域)中创建 HomeController。在该控制器上创建一个名为 Index 的操作方法。在那个 Index 方法中,将它们重定向到您真正希望它们开始的控制器。

在 global.asax 中,您可以依赖一个非常标准的默认路由,如下所示:

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

在 Home 控制器上的 Index 操作中,只需使用 RedirectToAction 将客户端重定向到新闻区域中的正确控制器并指定区域:

return RedirectToAction("IndexOfArticles", "Articles", new { area = "News" });

第二种技术是确定路线的优先级,以便它知道要使用哪个区域。这不需要任何根级控制器。只需添加一个看起来有点像这样的路由条目:

routes.MapRoute(
    "Default",
    "{controller}/{acion}/{id}",
    new {controller = "Articles", action = "IndexOfArticles", id = UrlParameters.Optional},
    new[] {"YourApplication.News"}
);

这样做的缺点是第 4 个参数(命名空间)将应用于所有请求,因此它可能会导致更多内容被重定向到您的特定新闻区域,而不是您想要的。最好对第二个参数进行更具体的处理,这样该路由就不会捕获其他请求……也许将第二个参数设置为空字符串,以便它仅捕获站点根请求。

于 2010-09-10T13:08:54.923 回答
2

到您的区域的自定义路线应该在您的 AreaRegistration 类中注册而不是在 Global.asx.cs

添加路由修改您的NewsAreaRegistration并在区域路由之后将新的默认路由添加到您的服务器。(这里的顺序很重要!)

默认路由应始终位于路由表的底部,以便匹配更具体的路由。

您在方法中的路线RegisterArea应如下所示:

        context.MapRoute(
            "News_default",
            "News/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );

        context.MapRoute(
            "DefaultStart",
            "",
            new { controller = "Articles", action = "IndexOfArticles"}
        );

更新:忘了提到您需要确保您Application_Start在 Global.asx.cs 文件的方法中注册了您的区域。

AreaRegistration.RegisterAllAreas();

更新 2:路由在 ASP.NET MVC 中的工作原理

我理解你的担心。让我简要解释一下路由是如何工作的。

在 ASP.NET MVc 中,有一个路由表用于匹配所有 url 请求。

当您在 Global.asx.cs 或 AreaRegistration 中注册路由时,这些路由会按照它们注册的顺序添加到路由表中(这就是顺序很重要的原因,我们应该将更具体的路由推到顶部,以便它们可以匹配)。

当涉及到区域路线(在AreaRegistration课程中注册的路线)。这些总是在 Global.asx.cs 文件中注册的任何路由之前添加到路由表的顶部(区域路由是第一个匹配的路由),因为否则您将错过匹配名为 News 的区域一个名为 News 的控制器。

如果您有多个区域,首先检查哪个区域的路线?我不是 100% 确定,但是通过实验我发现它们是按创建时间排序的,旧区域首先位于路由表的顶部。(这并不重要,因为你不会有两个同名的区域)

例子:

假设您创建了以下区域。News, Dashboard,Api

并将以下路由添加到您的 NewsAreaRegistration 以匹配根路由,如上面的示例所示

context.MapRoute(
        "DefaultStart",
        "",
        new { controller = "Articles", action = "IndexOfArticles"}
    );

您的路由表将如下所示:

No   Route Name                        URL                               Explanation 
1   News_default         News/{controller}/{action}/{id}          Default For News Area
2   DefaultStart         (empty)                                  Root Route (match root url)
3   Dashboard_default    Dashboard/{controller}/{action}/{id}     Default For Dashboard Area
4   Api_default          Api/{controller}/{action}/{id}           Default For Api Area
5   Default              {controller}/{action}/{id}               Default (No Areas)

现在,当您的应用程序收到请求时。它将逐个遍历路线并寻找匹配项。在我们的例子中,当您请求根 url 时。第二条路线将被匹配。并且因为我们为 controller = "Articles" 和 action ="IndexOfArticles" 设置了默认值,所以请求将被相应地重定向。

希望这会有所帮助。

于 2010-09-09T12:11:35.137 回答