ASP.NET MVC自定义视图引擎

   最近由于工作的关系,项目的ASP.NETmvc视图引擎是xslt的,公司的当然是异常的强大和健壮,怎奈我XSLT不太熟悉,至少没有熟悉到想html一样,所以第私底下连自己练习 先做个简单的视图引擎,至于为什么要用XSLT,自然是xslt+xml默认的解析也是异常的强大和健壮,还可以为项目奠定组件化,分布式,多线程并发等基础

  自定义ASP.NETMVC视图引擎,只需要实现接口IView和继承VirtualPathProviderViewEngine

在重写VirtualPathProviderViewEngine 时 主要目的是规定请求和视图和模板视图的文件路径和类型

例如

===

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace myview
{
    public class MyViewEngine:VirtualPathProviderViewEngine
    {

        private string _AppPath = string.Empty;

        //#region 属性 Properties
        //public static FileSystemTemplateLoader Loader { get; private set; }
        //public static StringTemplateGroup Group { get; private set; }
        //#endregion

        public MyViewEngine()
        {


            ViewLocationFormats = new[]{
                 "/Views/{1}/{0}.aspx"

            };
       

        }


        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
        {
            return this.CreateView(controllerContext, partialPath, String.Empty);
        }

        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
        {

            //还是在这个函数里根据规则匹配模板名称
            //      string masterPath =GetPath(controllerContext, MasterLocationFormats, "MasterLocationFormats",
            //masterName, controllerName, _cacheKeyPrefix_Master, useCache, out masterLocationsSearched);

            //base.FindView(controllerContext, viewPath, masterPath, true);

            //string controllername = controllerContext.RouteData.Values["controller"].ToString();
            ///Views/Shared/{0}.xslt

            if (!string.IsNullOrEmpty(masterPath))
                throw new Exception("此处不能指定试图的名称");
            string actionname = controllerContext.RouteData.Values["action"].ToString();
            masterPath = string.Format("/Views/Shared/{0}.xslt", actionname);
            return new xsltView(viewPath, masterPath);
            
        }
    }
}

==

ViewLocationFormats 中主要是 视图的文件路径,因为采用XML(内存生成)+xslt(负责解析转换)因此 请求的类型不变采用ASP.NETmvc默认的

"/Views/{1}/{0}.aspx" 就行,把xslt作为模板就行了

坦白的说,对ASP.NETmvc 机制不是很了解,开始一直在纠结 IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)

中masterPath的路径怎么一直为空,是配置有问题,还是逻辑有问题,纠结了一上午,最终下载了ASP.NETmvc源码查看一下,这这里还有其他函数用于寻找模板

GetPath(controllerContext, MasterLocationFormats, "MasterLocationFormats",
            //masterName, controllerName, _cacheKeyPrefix_Master, useCache, out masterLocationsSearched)

所以干脆自己找模板,也变成强制性的路径 masterPath = string.Format("/Views/Shared/{0}.xslt", actionname);

这样 就行了

模板引擎还需要实现自己的IView,对模板进行解析

===

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Xml;
using System.IO;
using System.Xml.Xsl;
using System.Web;

namespace myview
{
    public class xsltView:IView
    {

        // 视图文件的物理路径
        private string _viewPhysicalPath;
        // 视图文件的物理路径
        private string _xsltPhysicalPath;

        public xsltView(string viewPhysicalPath, string masterPhysicalPath)
        {
            _viewPhysicalPath = viewPhysicalPath;
            _xsltPhysicalPath = masterPhysicalPath;
        }


        void IView.Render(ViewContext viewContext, System.IO.TextWriter writer)
        {
          

            XslCompiledTransform transform = new XslCompiledTransform();
            //xslt文件的路径
          
            string XsltFileDir =System.Web.HttpContext.Current.Server.MapPath(_xsltPhysicalPath);
            try
            {
                transform.Load(XsltFileDir);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            MemoryStream stream = new MemoryStream();

            if (string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Params["debug"]))
            {
                try
                {
                    transform.Transform(XmlReader.Create(new StringReader(viewContext.ViewData["xmlcontent"].ToString())), null, stream);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                // transform.Transform(Server.MapPath("a.xml"), null, stream);
                stream.Position = 0;
                StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8);
                // 呈现出解析后的内容
                writer.Write(reader.ReadToEnd());
            }
            else
            {
                writer.Write(viewContext.ViewData["xmlcontent"].ToString());
            }
        }

       




    }
}

 

===

这里主要是调用xml的方法进行转换,然后直接输出

最后还需要一件事情要做

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using myview;

namespace MvcApplication5
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

            routes.MapRoute(
                "Default2", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterRoutes(RouteTable.Routes);
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new myview.MyViewEngine());

        }
    }
}

==================================

在这里初始化视图引擎就行了

使用就更简单了

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication5.Controllers
{
  
    public class HomeController : Controller
    {
      
        public ActionResult Index()
        {
            ViewData["Message"] = "Welcome to ASP.NET MVC!";
            ViewData["xmlcontent"] = @"<result>
                                   <h1>
                                    aaa
                                   </h1>
                                   </result>";
            return View();
        }

        public ActionResult About()
        {
            return View();
        }
    }
}

===

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="/result">
        
          <xsl:for-each select="h1">

            <xsl:value-of select="."/>  
          </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

接下来就得自己给自己开小灶研究一下xslt 和具体的ASP.NETmvc框架同时也对比一下JAVA的MVC框架,以前asp.net没有开源 总是被人鄙视不懂底层,现在这段历史终于过去了,因为XML要在内存中生成,可以很好的练习以前linq to xml,真是一句多的

 

 

test
上一篇:增加软链接


下一篇:使用docker 解决一个小问题,你也可能用的到