342

我一直在 SO 和 Google 上搜索可用于 ASP.NET MVC 的各种视图引擎的细分,但除了简单的高级描述视图引擎是什么之外,我没有找到更多。

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

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

4

6 回答 6

433

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标签在某些非常常见的条件下。
  • 封装性差+可重用性差:像调用普通方法一样调用 razor 模板是不切实际的——实际上,razor 可以调用代码但反之则不行,这会鼓励代码和表示的混合。
  • 语法非常面向 html;生成非 html 内容可能很棘手。尽管如此,razor 的数据模型本质上只是字符串连接,因此语法和嵌套错误既不会静态检测也不会动态检测,尽管 VS.NET 设计时帮助在一定程度上缓解了这种情况。可维护性和可重构性可能因此受到影响。
  • 没有记录的 API, http: //msdn.microsoft.com/en-us/library/system.web.razor.aspx

反例#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 语法”
  • 按需编译的视图(但没有可用的预编译)

缺点:

例子:

<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 是 .NET 平台上的Django 模板语言的实现,使用F# 语言

优点:


氨基甲酸酯

设计目标:

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

Haml 是一种标记语言,用于简洁地描述任何 Web 文档的 XHTML,而不使用内联代码……Haml 避免了将 XHTML 显式编码到模板中的需要,因为它实际上是 XHTML 的抽象描述,用一些代码来生成动态内容。

优点:

  • 简洁的结构(即 DRY)
  • 缩进良好
  • 结构清晰
  • C# Intellisense(适用于没有 ReSharper 的 VS2008)

缺点:

  • XHTML 的抽象,而不是利用对标记的熟悉程度
  • VS2010 没有智能感知

例子:

@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(智能感知、视图的编译时检查或重构)

例子:

#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 框架背后的概念(从里程碑 1 开始)。

优点:

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

缺点:

  • ...

例子:

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

火花视图引擎

设计目标:

这个想法是让 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 不太实用)。

于 2009-09-20T16:03:10.323 回答
18

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

提供一个简单的示例:

@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

于 2011-11-13T19:21:15.820 回答
11

我知道这并不能真正回答您的问题,但不同的视图引擎有不同的目的。例如,Spark View Engine旨在通过尝试使所有内容流畅和易读来消除您对“标签汤”的看法。

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

于 2009-09-20T15:49:23.970 回答
8

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

于 2010-04-30T21:10:34.910 回答
6

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

于 2010-02-25T19:48:57.747 回答
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>
于 2010-02-01T17:51:11.403 回答