使用ASP.NET MVC区域路由时出现404未找到错误

11

我在MVC 5中遇到了一个区域路由问题。当我浏览到/Evernote/EvernoteAuth时,会出现404资源找不到的错误。

我的区域如下:

Areas
    Evernote
        Controllers
            EvernoteAuthController
        Views
            EvernoteAuth
                Index.cshtml

EvernoteAreaRegistration.cs文件包含以下路由映射(更新:RegisterArea()未被调用,因此我执行了清理和重新构建。现在已被调用,但结果相同。):

public override void RegisterArea(AreaRegistrationContext context)
{
     context.MapRoute(
        "Evernote_default",
        "Evernote/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
     );
}
EvernoteAuthController的Index()方法只返回View()。
我的应用程序的RouteConfig.cs目前没有定义路由映射,但我在这里尝试手动“强制”实现它,如下所示:
routes.MapRoute(
    name: "EvernoteAuthorization",
    url: "Evernote/{controller}/{action}",
    defaults: new { controller = "EvernoteAuth", action = "Index", id = UrlParameter.Optional },
    namespaces: new string[] { "AysncOAuth.Evernote.Simple.SampleMVC.Controllers" }
);

无论这个路由图是否存在或被注释掉,我得到的结果都是一样的。

使用Phil Haack的asp.net mvc路由调试器,我发现我的路由匹配得很好,区域名、控制器名和操作方法名都匹配。我在控制器操作方法中设置了断点,但那些方法从未被执行。更新:当我浏览到/Evernote/EvernoteAuth时,那些方法从未被执行;然而,当我浏览到仅区域名称/Evernote时,一个EvernoteAuthController被实例化并调用Index()方法。(为什么该控制器被/Evernote实例化而不是/Evernote/EvernoteAuth?) 然后我收到了以下错误消息:

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/EvernoteAuth/Index.aspx
~/Views/EvernoteAuth/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/EvernoteAuth/Index.cshtml
~/Views/Shared/Index.cshtml
and so on...
在这种情况下,我相信 ~ = /(应用程序根目录)。因此,区域Areas\Evernote\Views没有被搜索到。
我该如何进行故障排除?
4个回答

25

重要的是在控制器中添加正确的命名空间。

  namespace YourDefaultNamespace.Areas.Evernote.Controllers
  {
    public class EvernoteAuthController : Controller
    { 
        ...
        ...
    }
  }

因此路由可以找到您的控制器。 现在,您必须使用该方法在Global.asax.cs中注册该区域。

AreaRegistration.RegisterAllAreas();

3
谢谢;当我从另一个项目复制现有的控制器时,发生了错误。命名空间很重要,必须正确。 - Catto
1
哦,我的天啊!这刚刚解决了我一个大问题,我困扰了将近两个小时!!!当然!这是常识!我把一个控制器从控制器文件夹移动到了一个区域,一直在想为什么它不起作用!现在它可以了:D 非常感谢! - Jose A

6

Application_Start方法中,要谨慎使用AreaRegistration.RegisterAllAreas();

如果您将AreaRegistration.RegisterAllAreas()放在Application_Start的最后,那么它将无效。

AreaRegistration.RegisterAllAreas()放在第一位,路由将成功执行。

示例:

 protected void Application_Start(object sender, EventArgs e)
 {
        AreaRegistration.RegisterAllAreas();  //<--- Here work

        FilterConfig.Configure(GlobalFilters.Filters);
        RouteConfig.Configure(RouteTable.Routes);

        AreaRegistration.RegisterAllAreas();  //<--- Here not work
 }

你的回答让我意识到我的 AreaRegistration.RegisterAllAreas(); 被注释掉了。谢谢。 - Word Rearranger

4
您在我的帖子中找到了 http://legacy.piranhacms.org/the-magic-of-mvc-routing-with-multiple-areas,您可能已经发现所有控制器都映射到默认路由(即您在路由配置中手动添加的路由)。如果它已添加到默认路由,则会搜索其视图的默认路由位置,即~/Views/...

因此,错误似乎真正出在区域没有正确配置。请确保在您的Global.asax.xs文件中有以下行:

AreaRegistration.RegisterAllAreas();

这是真正设置区域并确保当区域内的控制器被访问时,搜索该区域的视图目录的行,对于您的情况是〜/Areas/Evernote/Views。我的博客文章介绍了如何消除默认路由中映射到Evernote区域的控制器。
希望这有所帮助!
问候,
Håkan

@haken 谢谢你的回答。我已经逐步执行了代码,我的新区域确实被注册了。 - Howiecamp
我找到了问题所在。我的控制器类的命名空间与区域结构不匹配。当我将命名空间更改为Areas.Evernote.Controllers时,它就起作用了。我对此感到惊讶 - 为什么会有这个要求呢?或者,也许这不是一个要求,而是我设置了一些默认值? - Howiecamp

0
在我的情况下,global.asax.cs文件中Application_Start方法的配置顺序是:
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);

改变顺序使其正常工作。

GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接