采用xslt作为ASP.NETmvc的视图引擎有几个好处
1彻底的实现视图和逻辑的分离(采用ASPX你无法控制别人在ASPX里面是否写逻辑代码)
2彻底的实现强类型的MODEL(自己定义视图引擎只是先一种数据方式)
3借助MODEL序列化为XML,进行XSLT转换,实现页面个性定制
4xslt的基本语法可以完成一部分JS的工作,而这正是页面基本控件布局和展示所需要的
5xslt的自定义函数可以进行有效的扩展
以前的流不是很了解折腾了一周总算是明白了
一个典型的目录如下
文件的结构也是比较清晰的
实现仅需要实现一个借口和集成一个类
代码如下
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-width: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);
}