ASP.NET MVC视图引擎比较


339

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

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

有没有人遇到过这样的比较?


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

Answers:


430

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

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


System.Web.Mvc.WebFormViewEngine

设计目标:

用于向响应呈现Web窗体页面的视图引擎。

优点:

  • 随处可见,因为它随ASP.NET MVC一起提供
  • ASP.NET开发人员的熟悉经验
  • 智能感知
  • 可以使用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

设计目标:

优点:

  • 紧凑,富有表现力且流畅
  • 简单易学
  • 不是新语言
  • 具有出色的智能感
  • 可单元测试
  • 随处可见,随ASP.NET MVC一起提供

缺点:

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

贝尔维尤

设计目标:

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

抄网

设计目标:

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使用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模板语言的实现 。

优点:


纳姆

设计目标:

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

Haml是一种标记语言,用于简洁地描述任何Web文档的XHTML,而无需使用内联代码... 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项目Velocity的.NET端口 。

优点:

  • 容易读/写
  • 简洁的查看代码

缺点:

  • 视图上可用的辅助方法数量有限
  • 不自动具有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是JSTL的部分移植版, 结合了Tiles框架(从Mile stone 1开始)的概念。

优点:

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

缺点:

  • ...

例:

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

Spark View引擎

设计目标:

这个想法是让html主导流程,并使代码无缝地匹配。

优点:

  • 产生更具可读性的模板
  • C#Intellisense (适用于不带ReSharper的VS2008)
  • VS2010的SparkSense插件(与ReSharper配合使用)
  • 提供强大的绑定功能,以消除视图中的所有代码,并让您轻松发明自己的HTML标签

缺点:

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

例:

<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

设计目标:

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

优点:

  • StringTemplate Java开发人员熟悉

缺点:

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

翼节拍

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

优点:

  • 有效XML的编译时检查
  • 语法着色
  • 全面智能
  • 编译视图
  • 使用常规CLR类,函数等的可扩展性
  • 无缝的可组合性和可操作性,因为它是常规的F#代码
  • 可单元测试

缺点:

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

XsltViewEngine(MvcContrib)

设计目标:

从熟悉的XSLT构建视图

优点:

  • 无处不在
  • XML开发人员熟悉的模板语言
  • 基于XML
  • 经过时间考验
  • 可以静态检测语法和元素嵌套错误。

缺点:

  • 功能语言风格使流程控制变得困难
  • 不支持XSLT 2.0。(XSLT 1.0不太实用)。


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

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

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

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

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

17

我当前的选择是剃刀。它非常干净且易于阅读,并且使视图页面易于维护。还有智能感知支持,确实很棒。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


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

10

我知道这并不能真正回答您的问题,但是不同的View Engine具有不同的用途。在星火视图引擎,例如,目的是试图让一切流畅可读摆脱你的“标签汤”的观点。

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


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


5

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


4

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

图片说出一千个单词,标记示例就像是视图引擎的屏幕截图:)所以这是我最喜欢的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>

4
看起来太像冷融合了。我不喜欢这样将代码混合到标记中。变得难以维护。
敏捷绝地
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.