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,真是一句多的

 

 

你可能感兴趣的:(asp.net)