我一直在SO和Google上搜索可用于ASP.NET MVC的各种View Engine的分类,但是除了对View Engine是什么的简单高级描述之外,没有发现更多。

我并不一定要在各种情况下寻找“最佳”或“最快”,而是对主要参与者(例如默认的WebFormViewEngine,MvcContrib View Engine等)的优缺点进行一些现实世界的比较。我认为这对于确定从默认引擎进行切换是否对给定的项目或开发组是否有利很有帮助。

有人遇到这样的比较吗?

评论

具有讽刺意味的是,它“没有建设性”,但为那些看了将近45K次的参与者提供了很多价值。尽管社区有需求,SO仍然限制了自己的效用,这太糟糕了。我怀疑@ jeff-atwood会有这种​​感觉。

#1 楼

ASP.NET MVC视图引擎(社区Wiki)

由于似乎不存在完整的列表,因此让我们从SO开始。如果人们增加了他们的经验(尤其是其中之一的贡献者),那么这对于ASP.NET MVC社区可能具有巨大的价值。在这里实现IViewEngine(例如VirtualPathProviderViewEngine)的任何事情都是公平的。只需按字母顺序排列新的View Engine(将WebFormViewEngine和Razor放在顶部),然后尝试比较客观。


System.Web.Mvc.WebFormViewEngine

设计目标:


用于将Web表单页面呈现给响应的视图引擎。


优点:


随处可见,因为它附带了ASP.NET MVC。
为ASP.NET开发人员提供了熟悉的体验。
IntelliSense
可以使用CodeDom提供程序选择任何语言(例如C#,VB.NET,F#,Boo和Nemerle)
按需编译或预编译视图

缺点:


用法被存在混淆了不再适用于MVC的“经典ASP.NET”模式(例如ViewState PostBack)
可能有助于“标记汤”的反模式
代码块语法和强类型化可以在方式
IntelliSense强制执行的样式并不总是适用于内联代码块
在设计简单模板时可能会产生噪音

示例:

<%@ Control Inherits="System.Web.Mvc.ViewPage<IEnumerable<Product>>" %>
<% if(model.Any()) { %>
<ul>
    <% foreach(var p in model){%>
    <li><%=p.Name%></li>
    <%}%>
</ul>
<%}else{%>
    <p>No products available</p>
<%}%>



System.Web.Razor

设计目标:

优点:


紧凑,富有表现力和流畅性
易于学习
不是一种新语言
具有出色的Intellisense
可测试单元
无处不在,随ASP.NET MVC一起提供

缺点:


与上面提到的“标签汤”产生了稍微不同的问题。在服务器标记实际上提供围绕服务器和非服务器代码的结构的地方,Razor混淆了HTML和服务器代码,使纯HTML或JS开发面临挑战(请参阅Con Example#1),因为最终您不得不“转义” HTML和/或JavaScript。标签在某些非常常见的条件下。
封装性差/可重用性:像普通方法一样调用razor模板是不切实际的-在实践中razor可以调用代码,反之则不行,这会鼓励代码和表示的混合使用。
语法是非常基于html的;生成非HTML内容可能很棘手。尽管如此,剃刀的数据模型本质上只是字符串连接,因此虽然VS.NET设计时的帮助在某种程度上减轻了这种麻烦,但是语法和嵌套错误既不会静态也不会动态检测。因此,可维护性和可重构性会受到损害。

没有文档化的API,http://msdn.microsoft.com/zh-cn/library/system.web.razor.aspx


Con示例#1(注意“ string [] ...”的位置):

@{
    <h3>Team Members</h3> string[] teamMembers = {"Matt", "Joanne", "Robert"};
    foreach (var person in teamMembers)
    {
        <p>@person</p>
    }
}



Bellevue

设计目标:



将HTML视为一流的语言,而不是将其视为“纯文本”。
不要弄乱我的HTML!数据绑定代码(Bellevue代码)应与HTML分开。
强制严格的模型-视图分离




Brail

设计目标:


Brail视图引擎已从MonoRail移植到
,以与Microsoft ASP.NET MVC框架一起使用。有关Brail的简介,请参见Castle项目网站上的文档



优点:


以“手腕友好的python语法”为模型
按需编译视图(但不提供预编译)



设计用Boo语言编写的


示例:

<html>    
<head>        
<title>${title}</title>
</head>    
<body>        
     <p>The following items are in the list:</p>  
     <ul><%for element in list:    output "<li>${element}</li>"%></ul>
     <p>I hope that you would like Brail</p>    
</body>
</html>



Hasic


Hasic使用VB.NET的XML文字而不是像大多数其他视图引擎一样的字符串。


优点:


有效XML的编译时检查
语法着色
完整的智能感知
编译视图
使用常规CLR类,函数,等
,因为它是常规的VB.NET代码,所以具有无缝的可组合性和可操作性。
单元可测试

缺点:



性能:构建整个DOM在发送给客户之前。

示例:

Protected Overrides Function Body() As XElement
    Return _
    <body>
        <h1>Hello, World</h1>
    </body>
End Function



NDjango

设计目标:


NDjango使用F#语言在.NET
平台上实现
Django模板语言。


优点:


NDjango版本0.9.1.0在压力下似乎比WebFormViewEngine更稳定
带有语法着色,代码完成和按需输入类型诊断的Django模板编辑器(仅VS2010)
与ASP.NET,Castle MonoRail和Bistro MVC框架集成


NHaml

设计目标:


Rails Haml视图引擎的.NET端口。
从Haml网站上:

Haml是一种标记语言,已用于
简洁地描述
XHTML Web文档,而无需使用内联代码... Haml避免了
将XHTML显式编码到模板中的需求,因为它实际上是XHTML的抽象描述。 ,
机智某些代码可生成动态内容。




简洁的结构(即DRY)
缩进的
结构清晰

C#Intellisense(适用于不带ReSharper的VS2008)

缺点:


是XHTML的抽象,而不是利用标记的熟悉性
VS2010没有Intellisense

示例:

@type=IEnumerable<Product>
- if(model.Any())
  %ul
    - foreach (var p in model)
      %li= p.Name
- else
  %p No products available



NVelocityViewEngine(MvcContrib)

设计目标:


基于
NVelocity的视图引擎,它是流行的Java项目的.NET端口。
Velocity。


优点:


易于阅读/编写
简洁的视图代码

缺点:


有限的辅助方法在视图上可用
不会自动集成Visual Studio(IntelliSense,视图的编译时检查或重构)

示例:

#foreach ($p in $viewdata.Model)
#beforeall
    <ul>
#each
    <li>$p.Name</li>
#afterall
    </ul>
#nodata 
    <p>No products available</p>
#end



SharpTiles

设计目标:


SharpTiles是JSTL的部分移植
,与Tiles背后的概念结合在一起
框架(从Milestone 1开始)。




Java开发人员熟悉的
XML样式代码块

缺点:


...

示例:

<c:if test="${not fn:empty(Page.Tiles)}">
  <p class="note">
    <fmt:message key="page.tilesSupport"/>
  </p>
</c:if>



Spark View Engine

设计目标:


这个想法是允许html主导流程并适合的代码
无缝钢管sly。




产生更多可读的模板

C#Intellisense(适用于不带ReSharper的VS2008)

用于VS2010的SparkSense插件(可与ReSharper配合使用)
提供强大的绑定功能,以消除视图中的所有代码,并允许您轻松发明自己的HTML标记
< br缺点:


模板逻辑与文字标记之间没有明确的分隔(可以通过名称空间前缀来缓解)

示例:

<viewdata products="IEnumerable[[Product]]"/>
<ul if="products.Any()">
    <li each="var p in products">${p.Name}</li>
</ul>
<else>
    <p>No products available</p>
</else>

<Form style="background-color:olive;">
    <Label For="username" />
    <TextBox For="username" />
    <ValidationMessage For="username" Message="Please type a valid username." />
</Form>



StringTemplate视图引擎MVC

设计目标:



轻巧。没有创建页面类。
快速。模板被写入Response Output流。
已缓存。模板已缓存,但是利用FileSystemWatcher来检测文件更改。动态。模板可以通过代码即时生成。
灵活。模板可以嵌套到任何级别。
符合MVC原则。促进UI和业务逻辑的分离。所有数据都是在
时间之前创建的,并传递到模板。





熟悉的to StringTemplate Java开发人员

缺点:


简单的模板语法可能会干扰预期的输出(例如jQuery冲突)


> Wing Beats


Wing Beats是用于创建XHTML的内部DSL。它基于F#,包括ASP.NET MVC视图引擎,但也可以仅用于创建XHTML的功能。




有效XML的编译时检查
语法着色
完整的智能感知
已编译views
使用常规CLR类,函数等的可扩展性
由于是常规F#代码,因此具有无缝的可组合性和可操作性
可测试的单元

缺点:


您实际上不是编写HTML,而是在DSL中表示HTML的代码。

XsltViewEngine(MvcContrib)

设计目标:


从熟悉的XSLT构建视图




广泛使用的
熟悉的模板语言对于XML开发人员
基于XML的
经过时间检验的
可以静态检测语法和元素嵌套错误。

缺点:


功能语言样式使流程控制变得困难。
(可能?)不支持XSLT 2.0。 (XSLT 1.0不太实用)。



评论


@ BrianLy:因为F#是经过编译且具有功能的,这意味着它快速,可与其余运行时(至少直到c#4)和幂等才能互操作。我们一开始走了Ironpython路线,但对结果并不满意。就命名而言-我们欢迎提出建议:)

– kolosy
09-09-22 19:31

由于Brail的“缺点”部分,投了反对票。使用Boo作为语言当然不是一个缺点。

–欧文
2010-3-28在16:42

@Owen:是的。您必须从C#开发人员的角度来看这件事。您不想只使用模板引擎来学习另一种语言。 (自然,如果您已经知道Boo,那很酷,但是对于大多数C#开发人员来说,这是要克服的另一个障碍)

–克里斯蒂安·克劳瑟(Christian Klauser)
2010年6月1日于17:09

剃刀在那里。它应该更新为按字母顺序排列的Razor。

– mckamey
2010年7月22日在20:08

Boo是专业人士,而不是骗局。您已经在“ C#之外”了,模板越好越好。 C#并不是要在“模板”上下文中使用,它虽然具有一定的表现力,但并不“手腕友好”。另一方面,BOO的创建考虑到了这一点,因此使其更适合在模板环境中使用。

– Loudenvier
2011年5月16日15:44

#2 楼

我当前的选择是剃刀。它非常干净且易于阅读,并且使视图页面易于维护。还有智能感知支持,这确实很棒。 ALos与Web帮助程序一起使用时,它确实也非常强大。

要提供一个简单的示例:

@Model namespace.model
<!Doctype html>
<html>
<head>
<title>Test Razor</title>
</head>
<body>
<ul class="mainList">
@foreach(var x in ViewData.model)
{
<li>@x.PropertyName</li>
}
</ul>
</body>


就可以了。那是非常干净且易于阅读的。当然,这是一个简单的示例,但是即使在复杂的页面和表单上,也仍然非常易于阅读和理解。

关于缺点?到目前为止(我是新来的),当使用一些表单帮助程序时,缺少对添加CSS类引用的支持,这有点烦人。

谢谢
Nathj07

评论


h!刚刚注意到这个讨论有多久了。哦,好吧,也许有人会发现它,并且仍然会有用。

–nathj07
2011年11月13日19:22

#3 楼

我知道这并不能真正回答您的问题,但是不同的View Engine具有不同的用途。例如,Spark View Engine旨在通过使所有内容流利和可读性来摆脱“标签汤”的观点。

您最好的选择是仅看一下一些实现。如果它看起来很符合您的解决方案的意图,请尝试一下。您可以在MVC中混合和匹配视图引擎,因此,如果您决定不使用特定的引擎,这应该不是问题。

评论


感谢你的回答。当我发现“有人必须已经完成摘要”时,我实际上是从您的建议开始的。我希望对这些类型的设计目标和缺点进行汇总。 “ Spark View Engine ...旨在通过使所有内容流利和可读性来摆脱您对“标签汤”的看法。”这暗示了构建它的原因以及默认视图引擎的缺点。列表中还有一个项目符号。

– mckamey
09-09-20 15:56

#4 楼

检查此SharpDOM。这是一个c#4.0内部dsl,用于生成html以及asp.net mvc视图引擎。

评论


听起来这是构建视图的唯一合理方法。

–斯蒂芬·埃格蒙特(Stephan Eggermont)
2010年7月7日在8:22

您可以将其添加到Wiki的一般答案中吗?

–毛里西奥·谢弗(Mauricio Scheffer)
2010年8月31日13:59

我再也无法在CodePlex或Google上找到它。去哪了? (它仍在Codeproject上:codeproject.com/Articles/667581/…)

–贾里德·瑟斯克(Jared Thirsk)
2014年5月21日在21:34

#5 楼

我喜欢ndjango。它非常易于使用且非常灵活。您可以使用自定义标签和过滤器轻松扩展视图功能。我认为“与F#紧密相连”是优点而不是缺点。

#6 楼

我认为此列表还应包括每个视图引擎的示例,以便用户无需访问每个网站就可以了解每个视图引擎。

图片说出一千个单词,标记示例就像视图引擎的屏幕截图一样:)所以这是我最喜欢的Spark View Engine中的一个图片。

<viewdata products="IEnumerable[[Product]]"/>
<ul if="products.Any()">
  <li each="var p in products">${p.Name}</li>
</ul>
<else>
  <p>No products available</p>
</else>


评论


看起来太像冷融合了。我不喜欢将代码混入这样的标记中。变得难以维护。

–敏捷绝地
2010-12-30在4:55