aspp.netMVC自定义视图引擎

摘要:
使用xslt作为ASP。NET mvc有几个优点:1。完全分离视图和逻辑(您无法控制其他人是否使用ASPX在ASPX中编写逻辑代码)2。完全实现强类型模型(自己定义视图引擎只是一个数据方法)3。将模型序列化为XML,进行XSLT转换,实现页面定制。xslt的基本语法可以完成部分JS工作,这正是页面基本控件的布局和显示所需的5xslt自定义函数,可以有效扩展

采用xslt作为ASP.NETmvc的视图引擎有几个好处

1彻底的实现视图和逻辑的分离(采用ASPX你无法控制别人在ASPX里面是否写逻辑代码)

2彻底的实现强类型的MODEL(自己定义视图引擎只是先一种数据方式)

3借助MODEL序列化为XML,进行XSLT转换,实现页面个性定制

4xslt的基本语法可以完成一部分JS的工作,而这正是页面基本控件布局和展示所需要的

5xslt的自定义函数可以进行有效的扩展

以前的流不是很了解折腾了一周总算是明白了

一个典型的目录如下

QQ截图未命名

文件的结构也是比较清晰的

实现仅需要实现一个借口和集成一个类

代码如下

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;
        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)
        {
            if (!string.IsNullOrEmpty(masterPath))
                throw new Exception("此处不能指定试图的名称");
            string actionname = controllerContext.RouteData.Values["action"].ToString();
            string controllername = controllerContext.RouteData.Values["controller"].ToString();
            masterPath = string.Format("/Views/Shared/{0}/{1}.xslt",controllername ,actionname); 
            return new xsltView(viewPath, masterPath);
        }
    }
}
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 fs = new MemoryStream();
           
            XmlReaderSettings redset = new XmlReaderSettings();
            redset.ProhibitDtd = true;
            XsltArgumentList myarg = new XsltArgumentList();
            myarg.AddExtensionObject("myfn:utils", new MyXslExtension());

            System.Xml.Serialization.XmlSerializer xmlser = new System.Xml.Serialization.XmlSerializer(viewContext.ViewData.Model.GetType());
            xmlser.Serialize(fs, viewContext.ViewData.Model);

            fs.Position = 0;
         

            if (string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.Params["debug"]))
            {
                fs.Flush();
            

                MemoryStream stream = new MemoryStream();
                XmlReader viewxmlreader = XmlReader.Create(fs, redset);
                try
                {
                    transform.Transform(viewxmlreader, myarg, stream);
                    viewxmlreader.Close();
                    fs.Close();
                    fs.Dispose();
                  
                }
                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());
                stream.Close();
                reader.Close();
                reader.Dispose();
            }
            else
            {

                StreamReader reader2 = new StreamReader(fs, System.Text.Encoding.UTF8);
                writer.Write(reader2.ReadToEnd());
                fs.Close();
                fs.Dispose();
                reader2.Close();
                reader2.Dispose();
         
               
            }
        }

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace myview
{
    class MyXslExtension
    {
        public string FormatName(string firstName, string name)
        {
            return name + ", " + firstName;
        }
        public string GetLink()
        {
            return "http://www.cnblogs.com/qqloving/";
        }
    }
}
<?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"
                 xmlns:utils="myfn:utils"
                exclude-result-prefixes="msxsl">
 
 
  <xsl:output
             method="html"
             encoding="utf-8"
             doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
             doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" omit-xml-declaration="yes" />

    <xsl:template match="/">
      <div style=" border-style:solid; border-1px;">
        <table class="style1">
  
              
            <xsl:for-each select="*">
       <tr>
            <td> 0
              <xsl:value-of select="@Name"/>
              <!--一 @表示匹配当前的属性 -->     
            </td>
         <td>1
           <xsl:value-of select="."/>
           <!--一 .表示匹配当前的值 -->
         </td>

         <td>2
           <xsl:value-of select="node()"/>
           <!--一 node()表示获取当前的值 -->
         </td>

         <td>
           3
           <xsl:value-of select="name()"/>
           <!--一 name()表示获取当前节点的名称 -->
         </td>
         <td>
           4
           <xsl:value-of select="utils:GetLink()"/>
           <!--一 name()表示获取当前节点的名称 -->
         </td>
          </tr>
             
              
            </xsl:for-each>
         
              
       
        </table>
      </div>
    </xsl:template>
</xsl:stylesheet>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Xml.Serialization;
namespace MvcApplication5.Models
{


    [Serializable]
    public class ChangePasswordModel
    {
      
        public string OldPassword { get; set; }

     
        public string NewPassword { get; set; }

        
        public string ConfirmPassword { get; set; }
    }
}
 public ActionResult Index()
        {
            ChangePasswordModel MYMODEL = new ChangePasswordModel();
            MYMODEL.ConfirmPassword = "123";
            MYMODEL.NewPassword = "456";
            MYMODEL.OldPassword = "345";

            return View(MYMODEL);
        }

免责声明:文章转载自《aspp.netMVC自定义视图引擎》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Prism初研究之使用Prism 5.0开发模块化应用jquery.mobile.js学习下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Protobuf 语言指南(proto3)

Protobuf 语言指南(proto3)Protocol Buffer是Google的语言中立的,平台中立的,可扩展机制的,用于序列化结构化数据 - 对比XML,但更小,更快,更简单。您可以定义数据的结构化,然后可以使用特殊生成的源代码轻松地在各种数据流中使用各种语言编写和读取结构化数据。 定义消息类型 先来看一个非常简单的例子。假设你想定义一个“搜索...

wxpython ItemContainer

ItemContainer 是 很多可以添加string item的部件的父类,封装很多有用的方法,可以用来获取部件的被选中item 的string 如wx.ListBox ,wx.CheckListBox,wx.Choice,wx.ComboBox。 这些部件可以添加string ,并且内部对它们索引访问。  string GetString(self,...

ToString和Convert.ToString处理null值

http://www.cnblogs.com/qinge/p/5687806.html文章来源 1.Convert.ToString能处理字符串为null的情况。 测试代码如下: 1 2 3 4 5 6 static void Main(string[] args) {   string msg = null;   Console.W...

获取Android设备唯一标识码

概述 有时需要对用户设备进行标识,所以希望能够得到一个稳定可靠并且唯一的识别码。虽然Android系统中提供了这样设备识别码,但是由于Android系统版本、厂商定制系统中的Bug等限制,稳定性和唯一性并不理想。而通过其他硬件信息标识也因为系统版本、手机硬件等限制存在不同程度的问题。 下面收集了一些“有能力”或“有一定能力”作为设备标识的串码。 DE...

DELPHI 字符串分割处理

DELPHI 字符串分割处理 Code 1Function FindStr(BegSprStr,EdSpStr:String;var Source:String):String;  2var  3BegStr1Len,EdSpStr2Len,BegStr1Index,EdSpStr2index:integer;  4Temp:String;  5begi...

java常用加解密工具类

packagecom.sh.springboottdemo2.util; importcom.sun.org.apache.xerces.internal.impl.dv.util.Base64; importjavax.crypto.Cipher; importjavax.crypto.KeyGenerator; importjavax.crypt...