[英]How to override a nopcommerce view file with a view file inside the plugin?
我想覆蓋位於以下位置的nopcommerce視圖:
Nop.Admin/Views/Category/Tree.cshtml
以及我在我的插件文件夾中開發的視圖:
Views/Misc/Tree.cshtml
我該怎么做?
試試這篇我寫過的詳細文章: 3種在nopCommerce插件中顯示視圖的方法(嵌入式資源,主題覆蓋和自定義視圖引擎)
@wooncherk的自定義視圖引擎非常適合准備我們的視圖,以便將來輕松覆蓋。 但是,當涉及覆蓋現有核心視圖時,它不足,因為nopCommerce給予管理視圖優先於我們的自定義視圖。 這可以在GetPath()
的虛方法GetPath()
中Nop.Web.Framework.Themes.ThemeableVirtualPathProviderViewEngine.cs
。 對於那些想知道的人, ThemeableVirtualPathProviderViewEngine
是由ThemeableRazorViewEngine
繼承的類, ThemeableRazorViewEngine
后者又由@wooncherk的CustomViewEngine
類繼承。
參考上面關於ThemeableVirtualPathProviderViewEngine
的屏幕截圖,如箭頭所示,這兩行確認管理視圖的優先級始終高於我們的自定義視圖
我設法擴展@wooncherk的自定義視圖引擎方法,以滿足覆蓋現有管理核心視圖的需求。 這涉及覆蓋虛擬方法GetPath()
並將其復制到CustomViewEngine
類中。 在這一點上,刪除兩個罪魁禍首甚至整個小黑客代碼塊似乎是合乎邏輯的,但不要,它會導致異常
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[Nop.Admin.Models.Cms.RenderWidgetModel]', but this dictionary requires a model item of type 'System.Collections.Generic.List`1[Nop.Web.Models.Cms.RenderWidgetModel]'.
新的CustomViewEngine
將如下:
public class CustomViewEngine: ThemeableRazorViewEngine {
private readonly string[] _emptyLocations = null;
public CustomViewEngine() {
PartialViewLocationFormats = new[] {
"~/Administration/CustomExtension/Views/{1}/{0}.cshtml",
"~/Administration/CustomExtension/Views/Shared/{0}.cshtml"
};
ViewLocationFormats = new[] {
"~/Administration/CustomExtension/Views/{1}/{0}.cshtml",
"~/Administration/CustomExtension/Views/Shared/{0}.cshtml"
};
}
protected override string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations, string locationsPropertyName, string name, string controllerName, string theme, string cacheKeyPrefix, bool useCache, out string[] searchedLocations) {
searchedLocations = _emptyLocations;
if (string.IsNullOrEmpty(name)) {
return string.Empty;
}
string areaName = GetAreaName(controllerContext.RouteData);
//little hack to get nop's admin area to be in /Administration/ instead of /Nop/Admin/ or Areas/Admin/
if (!string.IsNullOrEmpty(areaName) && areaName.Equals("admin", StringComparison.InvariantCultureIgnoreCase)) {
var newLocations = areaLocations.ToList();
newLocations.Insert(0, "~/Administration/Views/{1}/{0}.cshtml");
newLocations.Insert(0, "~/Administration/Views/Shared/{0}.cshtml");
//Insert your custom View locations to the top of the list to be given a higher precedence
newLocations.Insert(0, "~/Administration/CustomExtension/Views/{1}/{0}.cshtml");
newLocations.Insert(0, "~/Administration/CustomExtension/Views/Shared/{0}.cshtml");
areaLocations = newLocations.ToArray();
}
bool flag = !string.IsNullOrEmpty(areaName);
List<ViewLocation> viewLocations = GetViewLocations(locations, flag ? areaLocations : null);
if (viewLocations.Count == 0) {
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Properties cannot be null or empty.", new object[] { locationsPropertyName }));
}
bool flag2 = IsSpecificPath(name);
string key = CreateCacheKey(cacheKeyPrefix, name, flag2 ? string.Empty : controllerName, areaName, theme);
if (useCache) {
var cached = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, key);
if (cached != null) {
return cached;
}
}
if (!flag2) {
return GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, theme, key, ref searchedLocations);
}
return GetPathFromSpecificName(controllerContext, name, key, ref searchedLocations);
}
}
請注意,在罪魁禍首行下方添加了兩行,以使我們的自定義視圖具有更高的優先級。
最后,我們需要修改RouteProvider.cs
public class RouteProvider : IRouteProvider {
public void RegisterRoutes(RouteCollection routes) {
//Insert our CustomViewEngine into the top of the System.Web.Mvc.ViewEngines.Engines Collection to be given a higher precedence
System.Web.Mvc.ViewEngines.Engines.Insert(0, new CustomViewEngine());
}
public int Priority {
get {
return 1;
}
}
}
就是這樣。 現在將自定義視圖/部分視圖放入視圖位置,在這種情況下它們是
~/Administration/CustomExtension/Views/{1}/{0}.cshtml
~/Administration/CustomExtension/Views/Shared/{0}.cshtml
其中{1}是您要覆蓋的Controller的名稱,{0}是您要覆蓋的視圖/局部視圖的名稱。
例如,如果要覆蓋Nop.Admin/Views/Category/Tree.cshtml
,請將自定義Tree.cshtml
放在Nop.Admin/CustomExtension/Views/Category/Tree.cshtml
。
Twisted Whisper有正確的答案,但我想我會分享一個博客文章的鏈接,深入討論這個(更多關於自定義視圖引擎如何工作以及使用這種技術的其他優點)在這里看到:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.