首先,抱歉很长时间的问题。我知道阅读和回答长期问题是痛苦的,但我必须清楚地解释我的情况。最近,我发现自己在ASP.NET MVC应用程序中复制视图并且不做任何改动或仅改变一些事情,通常是BeginForm("actionName", "controllerName")
上的控制器名称(幸运的是,这可以在视图内部解决)。不久,我的主要目的是消除重复的观点。
原因是我有不同的控制器具有类似的功能。它们看起来与用户相同,但控制器的计算结果非常不同。更具体地说,我有四个名为 InitialReport,CorrectionReport,InitialReportReview,CorrectionReportReview 的控制器。 InitialReport , CorrectionReport 和 InitialReportReview,CorrectionReportReview 的视图几乎完全相同。所以我想做的是消除重复的视图并为夫妻创建共享视图。
我的问题是,我不想将所有视图都放到 Shared 视图文件夹中,因为它们太多而无法放入此文件夹。此外,控制器中的操作名称重叠。假设我在所有四个控制器中都有ReportPayments
动作方法,因此视图名称也会重叠。但是,InitialReport
和InitialReportReview
的视图必须不同。所以我在共享视图文件夹中添加了两个文件夹,名为 Report (对于 InitialReport,CorrectionReport )和 ReportReview (对于 InitialReportReview,CorrectionReportReview )。我计划将所有共享视图分别添加到 Report 和 ReportReview 子文件夹。现在的问题是,查看查找位置必须动态更改以适应"控制器类型"。例如,如果我在InitialReport
控制器中并且我导航到ReportPayments
操作,则必须从〜/ Views / Shared / Report / ReportPayments.cshtml <加载视图/ em>,但如果我在InitialReportReview
控制器中,那么视图应该从〜/ Views / Shared / ReportReview / ReportPayments.cshtml 加载。
作为我创建自定义视图引擎的解决方案,我覆盖FindView
方法并根据控制器名称设置ViewLocationFormats
。
public class ExtendedRazorViewEngine
: RazorViewEngine
{
string[] DefaultViewLocations { get; set; }
string[] ReportViewLocations { get; set; }
string[] ReportReviewViewLocations { get; set; }
public ExtendedRazorViewEngine()
{
// Get the copy of default view locations
DefaultViewLocations = new string[ViewLocationFormats.Length];
ViewLocationFormats.CopyTo(DefaultViewLocations, 0);
// Initialize ReportViewLocations
List<string> customReportViewLocations = new List<string>
{
"~/Views/Shared/Report/{0}.cshtml"
};
ReportViewLocations = DefaultViewLocations
.Union(customReportViewLocations)
.ToArray();
// Initialize ReportReviewViewLocations
List<string> customReportReviewViewLocations = new List<string>
{
"~/Views/Shared/ReportReview/{0}.cshtml"
};
ReportReviewViewLocations = DefaultViewLocations
.Union(customReportReviewViewLocations)
.ToArray();
}
public override ViewEngineResult FindView(
ControllerContext controllerContext,
string viewName,
string masterName,
bool useCache)
{
// Get controller name
string controllerName = controllerContext.RouteData.GetRequiredString("controller");
// Set view search locations
if (controllerName.EndsWith("ReportReview"))
ViewLocationFormats = ReportReviewViewLocations;
else if (controllerName.EndsWith("Report"))
ViewLocationFormats = ReportViewLocations;
else
ViewLocationFormats = DefaultViewLocations;
return base.FindView(controllerContext, viewName, masterName, useCache);
}
}
我已将ExtendedRazorViewEngine
注册为默认视图引擎,似乎工作正常。但我几乎没有问题。有一个question和answer与我的相似(不完全相同),确实非常有用,但它没有回答我的问题。
FindView
方法被击中两次。为什么?我复制了视图引擎并在一个几乎空的MVC应用程序中进行了测试,同样的事情也发生在那里,所以我认为它与我的应用程序无关。答案 0 :(得分:1)
我认为你正在努力实现这一目标。将View放在Shared文件夹中似乎要简单得多。但是如果您不想这样做,即使它不在共享文件夹中,您仍然可以调用View。
从视图:
@Html.Partial("~/Views/ReportReview/InitialReport.cshtml")
或来自控制器:
return this.View("~/Views/ReportReview/InitialReport.cshtml");
所以如果我是你,我会创建一次这些视图,然后从其他视图或控制器中调用它。这样您就不必重复代码,也不必创建自定义视图引擎(我想这将是多年来保持的熊)。