Asp.net mvc 为什么MVC会在完整视图和部分视图中同时寻找.aspx和.ascx?

Asp.net mvc 为什么MVC会在完整视图和部分视图中同时寻找.aspx和.ascx?,asp.net-mvc,asp.net-mvc-partialview,Asp.net Mvc,Asp.net Mvc Partialview,我刚刚遇到一个问题,我有一个视图(FindUser.aspx)试图渲染部分视图(FindUser.ascx)。视图的默认搜索路径在各种文件夹中查找以视图命名的文件。令人惊讶的是,对于视图,它会查找扩展名为.aspx或.ascx的文件。局部视图使用相同的列表 因为我将这两个文件命名为相同的文件,所以视图解析会反复首先查找页面,并陷入一个无休止的循环 我知道我可以通过调用视图和局部视图的不同名称,或者将我的搜索位置更改为.aspx(仅适用于视图)和.ascx(仅适用于局部视图),来解决此问题 我的问

我刚刚遇到一个问题,我有一个视图(FindUser.aspx)试图渲染部分视图(FindUser.ascx)。视图的默认搜索路径在各种文件夹中查找以视图命名的文件。令人惊讶的是,对于视图,它会查找扩展名为.aspx或.ascx的文件。局部视图使用相同的列表

因为我将这两个文件命名为相同的文件,所以视图解析会反复首先查找页面,并陷入一个无休止的循环

我知道我可以通过调用视图和局部视图的不同名称,或者将我的搜索位置更改为.aspx(仅适用于视图)和.ascx(仅适用于局部视图),来解决此问题


我的问题是,为什么MVC默认同时考虑这两个扩展?视图==页面==.aspx和部分视图==控件==.ascx似乎更有意义。那么,为什么要把水弄脏呢?

因为不管是否局部,一个视图仍然是一个视图。拥有FindUser.aspx和FindUser.ascx与拥有两个同名的常规视图是一样的。

值得一提的是,我在我所有的.ascx ViewUserControls的名称后面加上了“Control”。所以我会使用
FindUser.aspx
FindUserControl.ascx
。虽然不能解决问题,但它可以通过避免命名冲突来帮助您避免问题。

您可以在渲染视图时为MVC提供直接路径。假设我在我的
主页
文件夹中有一个
Foo.aspx
,在
共享
文件夹中有一个
Foo.ascx
部分视图。在行动方法中,您可以执行以下任一操作:

return View("~/Views/Shared/Foo.ascx"); // or
return View("~/Views/Home/Foo.aspx");

而且它将得到您正在寻找的正确视图。

我认为避免出现问题的方法是使用不同的视图名称。您可能不应该有两个文件名仅在扩展名上不同的视图。但是,如果确实需要严格的页面=视图,控件=部分映射,只需从WebFormViewEngine继承创建自己的ViewEngine并更改视图位置格式:

public class MyWebFormViewEngine : WebFormViewEngine {
    public MyWebFormViewEngine() {
        base.ViewLocationFormats 
          = new string[] {"~/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx" };
        base.PartialViewLocationFormats 
          = new string[] { "~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.ascx" };
    }
}
然后在应用程序_Start()中将其配置为视图引擎:


原因
视图==ASP.NET MVC中的用户控件

修复
使用不同的名称

提示

使用下划线前缀命名usercontrols是一种常见的惯例。

如果使用区域,则必须在构造函数中添加其他位置格式:

public class ExtensionBasedWebFormViewEngine : WebFormViewEngine
{
  public ExtensionBasedWebFormViewEngine()
  {
     ViewLocationFormats = new[] {"~/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx"};
     AreaViewLocationFormats = new[] {"~/Areas/{2}/Views/{1}/{0}.aspx", "~/Areas/{2}/Views/Shared/{0}.aspx"};

     PartialViewLocationFormats = new[] {"~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.ascx"};
     AreaPartialViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.ascx", "~/Areas/{2}/Views/Shared/{0}.ascx" };
  }
}

不要在ASP.NET MVC上下文中使用“控制”术语。这只是一个局部视图,除非您执行局部请求(即使这样,也有更合适的名称,如子控制器或小部件)。标记部分视图的常用约定-名称中的下划线前缀。@Arnis-该类实际上是ViewUserControl-我认为在类或视图的名称中使用它没有问题。
public class ExtensionBasedWebFormViewEngine : WebFormViewEngine
{
  public ExtensionBasedWebFormViewEngine()
  {
     ViewLocationFormats = new[] {"~/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx"};
     AreaViewLocationFormats = new[] {"~/Areas/{2}/Views/{1}/{0}.aspx", "~/Areas/{2}/Views/Shared/{0}.aspx"};

     PartialViewLocationFormats = new[] {"~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.ascx"};
     AreaPartialViewLocationFormats = new[] { "~/Areas/{2}/Views/{1}/{0}.ascx", "~/Areas/{2}/Views/Shared/{0}.ascx" };
  }
}