自定义ViewEngine
为什么需要自定义ViewEngine
我们先看一段最普通代码:
public class HomeController : Controller { public ActionResult Index() { return View(); } }
上面的View查找路径为:
"~/Views/Home/Index.cshtml"
这是默认的ViewEngine(RazorViewEngine)的查找规则。当它不能满足我们特殊的View路径查找需求时,就需要通过自定义ViewEngine实现。
在nopCommerce中, 它的后台管理是一个单独的工程,工程路径为Web\Administration,访问admin/home/index时需要返回
"~/Administration/Views/Home/Index.cshtml"
实现方法
1,实现IViewEngine接口,但一般不这么做,原因是太费劲了
2,继承BuildManagerViewEngine,修改它的ViewLocationFormats参数。
public MyViewEngine(IViewPageActivator viewPageActivator) : base(viewPageActivator) { ViewLocationFormats = new[]{ //default "~/Views/{1}/{0}.cshtml", "~/Views/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml", //Admin "~/administrator/Views/{1}/{0}.cshtml", "~/administrator/Views/{1}/{0}.vbhtml", "~/administrator/Views/Shared/{0}.cshtml", "~/administrator/Views/Shared/{0}.vbhtml", }; FileExtensions = new[] { "cshtml" }; }
类关系:BuildManagerViewEngine:VirtualPathProviderViewEngine:IViewEngine
最后只需在Global.asax中使用它:
ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new MyViewEngine());
关于nopCommerce中的ViewEngine
按照上面思路实现的ViewEngine有一个缺陷,当项目中存在多个area,area下又存在相同的Controller和action时,返回的View将不正确。
nopCommerce的admin有一个HomeController,如主站点也有一个,上面的做法返回的View将一直是"~/Views/Home/Index.cshtml",因为它最先匹配。
解决办法:根据area通过动态修改areaLocations。
下面是部分关键代码(位于ThemeableVirtualPathProviderViewEngine.cs)
protected virtual string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations, string locationsPropertyName, string name, string controllerName, string theme, string cacheKeyPrefix, bool useCache, bool mobile, out string[] searchedLocations) { ..... var newLocations = areaLocations.ToList(); newLocations.Insert(0, "~/Administration/Views/{1}/{0}.cshtml"); newLocations.Insert(0, "~/Administration/Views/{1}/{0}.vbhtml"); newLocations.Insert(0, "~/Administration/Views/Shared/{0}.cshtml"); newLocations.Insert(0, "~/Administration/Views/Shared/{0}.vbhtml"); areaLocations = newLocations.ToArray(); } ...... }
相关链接:Walkthrough: Creating an ASP.NET MVC Areas Application Using Multiple Projects
签名:删除冗余的代码最开心,找不到删除的代码最痛苦!