• 自定义ViewEngine


    为什么需要自定义ViewEngine

    我们先看一段最普通代码:

    View Code
        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参数。   

    View Code
     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)

    View Code
    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

  • 相关阅读:
    处理流之转换流
    处理流之缓冲流 buffered
    java学习笔记 字符流Reader与Writer
    java学习笔记 OutputStream与InputStream
    java学习笔记 Map接口
    java 学习笔记 Iterator 迭代器
    java学习笔记 genenic 范形
    应急响应介绍
    安全之红蓝对抗简介
    密码学基础下篇
  • 原文地址:https://www.cnblogs.com/season2009/p/2745152.html
Copyright © 2020-2023  润新知