使用MVC 5 RouteArea属性时的默认视图区域无法找到 [英] Default area view cannot be found when using MVC 5 RouteArea attribute

查看:671
本文介绍了使用MVC 5 RouteArea属性时的默认视图区域无法找到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多个区域的MVC5项目。我有一个默认的区域(名为默认),并在其中,一个默认的控制器(名为 DefaultController )。这是在站点路由访问。

  [RouteArea]
公共类DefaultController:控制器
{
    [路线]
    公众的ActionResult指数()
    {
        返回查看(「指数」);
    }
}公共静态无效的RegisterRoutes(RouteCollection路线)
{
    routes.LowercaseUrls = TRUE;    routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);    routes.MapMvcAttributeRoutes();    routes.MapRoute(
        名称:默认,
        网址:{控制器} / {行动} / {ID}
        默认:新{控制器=默认,行动=索引,ID = UrlParameter.Optional},
        命名空间:新[] {MyProject.Areas.Default.Controllers}
    );
}

控制器是否正确装入,但视图(位于区/默认/查看/默认/ Index.cshtml )无法找到。为什么不MVC在正确的地方看?

 视图索引或它的主人没有被发现或没有视图引擎支持搜索位置。在以下地点被搜查:
〜/地区/控制器/视图/默认/的Index.aspx
〜/地区/控制器/视图/默认/ Index.ascx
〜/地区/控制器/查看/共享/的Index.aspx
〜/地区/控制器/查看/共享/ Index.ascx
〜/查看/默认/的Index.aspx
〜/查看/默认/ Index.ascx
〜/查看/共享/的Index.aspx
〜/查看/共享/ Index.ascx
〜/地区/控制器/视图/默认/ Index.cshtml
〜/地区/控制器/视图/默认/ Index.vbhtml
〜/地区/控制器/查看/共享/ Index.cshtml
〜/地区/控制器/查看/共享/ Index.vbhtml
〜/查看/默认/ Index.cshtml
〜/查看/默认/ Index.vbhtml
〜/查看/共享/ Index.cshtml
〜/查看/共享/ Index.vbhtml


解决方案

我看到两个选项:


  1. 获取明确,并指定 AREANAME [RouteArea(默认,区preFIX =)] ,其中默认是您所在地区的名称,设置区域preFIX =获取应用程序的根目录下的区域。

  2. 更改命名空间的控制器在这样的最后部分符合您所在区域的名称。

请注意,如果您所在地区的preFIX是根(),你必须非常明确的跟你的行动 [路线(...)] 属性,以便它们不贪婪地声称所有路由的应用程序,并让你摸不着头脑的原因,完全是另外一个摆。

背景

在该 RouteAreaAttribute 而不提供 AREANAME AREANAME 提供的是空,你可能会得到这个奇怪的错误,或者您的行为可能会使用不正确的观点(例如,如果你已经创建了〜/查看/共享/ Index.cshtml 用于其他目的)。

的<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.mvc.routeareaattribute.areaname(v=vs.118).aspx\"相对=nofollow> RouteAreaAttribute.AreaName 文档是有帮助的:


  

(该AREANAME属性)得到的区域名称为在控制器中定义的所有的路由设置。如果该值为空,企图将作出推断目标控制器的命名空间的区域名称。


通过应用 [RouteArea] 到控制器的 AREANAME 默认为空,导致一些逻辑来接管将推断目标控制器的命名空间的区域名称。显然推断涉及抓住了命名空间的最后一部分,传统上这部分是控制器,因为MVC开发者都在控制器文件夹中创建自己的控制器,默认情况下Visual Studio的基于文件夹结构决定了C#类的命名空间。

要证明我的观点,你可以从 MyProject.Areas.Default.Controllers 的DefaultController的命名空间更改为 MyProject.Areas.Default ,斩去.Controllers。如果重建,并参观该操作它会寻找下的地区/默认文件夹视图就像我们都期望:

 〜/地区/默认/查看/默认/的Index.aspx
〜/地区/默认/查看/默认/ Index.ascx
...

而不是像下没人了区/控制器文件夹中预计:

 〜/地区/控制器/视图/默认/的Index.aspx
〜/地区/控制器/视图/默认/ Index.ascx
...

我明白为什么开发商选择做这种方式,但很不幸,他们忽略了我们如何被教导要组织ASP.NET MVC code和如何Visual Studio中增加领域和控制器项目。这不完全是一个错误,而不是它的东西比这更微妙和令人沮丧的。

I have an MVC5 project with multiple areas. I have a default area (named Default) and within it, a default controller (named DefaultController). This is accessible at site route.

[RouteArea]
public class DefaultController : Controller
{
    [Route]
    public ActionResult Index()
    {
        return View("Index");
    }
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.LowercaseUrls = true;

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapMvcAttributeRoutes();

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional },
        namespaces: new[] { "MyProject.Areas.Default.Controllers" }
    );
}

The controller is correctly loaded, but the view (located at Areas/Default/Views/Default/Index.cshtml) cannot be found. Why is MVC not looking in the right place?

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Areas/Controllers/Views/Default/Index.aspx
~/Areas/Controllers/Views/Default/Index.ascx
~/Areas/Controllers/Views/Shared/Index.aspx
~/Areas/Controllers/Views/Shared/Index.ascx
~/Views/Default/Index.aspx
~/Views/Default/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Areas/Controllers/Views/Default/Index.cshtml
~/Areas/Controllers/Views/Default/Index.vbhtml
~/Areas/Controllers/Views/Shared/Index.cshtml
~/Areas/Controllers/Views/Shared/Index.vbhtml
~/Views/Default/Index.cshtml
~/Views/Default/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

解决方案

I see two options:

  1. Get explicit and specify the areaName with [RouteArea("Default", AreaPrefix = "")] where "Default" is the name of your area and setting AreaPrefix = "" gets the area in the root of your application.
  2. Change the namespace your controller is in so that the last part matches your area's name.

Note that if your area's prefix is the root ("") you need to be very explicit with your action [Route("...")] attributes so that they don't greedily claim all of the routes in your application, and leave you scratching your head for a whole other slew of reasons.

Background

When the RouteAreaAttribute is applied without supplying the areaName or the areaName supplied is null you may get this odd error, or your action may use an incorrect view (if for example you have created ~/Views/Shared/Index.cshtml for some other purpose).

The RouteAreaAttribute.AreaName docs are helpful:

(The AreaName property) gets the area name to set for all the routes defined in the controller. If the value is null, an attempt will be made to infer the area name from the target controller's namespace.

By applying [RouteArea] to your controller the areaName defaults to null which causes some logic to take over that will "infer the area name from the target controller's namespace." Apparently inferring involves grabbing the last part of the namespace, traditionally that part is "Controllers" because MVC developers have been taught to create their controllers in the Controllers folder, and by default Visual Studio determines a C# class' namespace based on folder structure.

To prove my point you can change the DefaultController's namespace from MyProject.Areas.Default.Controllers to MyProject.Areas.Default, chopping off ".Controllers". If you rebuild and visit that action it will look for views under the "Areas/Default" folder like we all expect:

~/Areas/Default/Views/Default/Index.aspx
~/Areas/Default/Views/Default/Index.ascx
...

Instead of under the "Areas/Controllers" folder like no one expects:

~/Areas/Controllers/Views/Default/Index.aspx
~/Areas/Controllers/Views/Default/Index.ascx
...

I get why the developers chose to do it this way, but it's unfortunate they ignored how we've been taught to organize ASP.NET MVC code and how Visual Studio adds areas and controllers to projects. It's not exactly a bug, instead it's something more subtle and frustrating than that.

这篇关于使用MVC 5 RouteArea属性时的默认视图区域无法找到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆