使用替代ASP.NET MVC视图引擎有哪些好处?

11

我看过了常见的选择...Spark、NHaml等,它们似乎都是为那些不熟悉 <% %> 语法的人提供的语法糖。除此之外,还有其他实际的好处吗?对我来说,语法糖并不足以成为更换整个视图引擎的充分理由。

迄今为止发布的原因:

  1. 更容易从不同平台过渡
  2. 更自然的上下文切换
  3. 更好的关注点分离
  4. 代码行数更少
  5. 更好的抵抗跨站脚本攻击
  6. 更好的 XHTML 兼容性

接受了bzlm的答案,因为更无缝的代码概念似乎是核心思想。但是让我倾向于这个答案的是loudej的评论。 - Robert Harvey
是的,“避免 <% } } %> 猎奇游戏”已经足以放弃 <% %> 语法了。 :) - bzlm
4个回答

8
人们对于 <% %> 语法感到不舒服的原因并不是它包含了大量的语法盐,而是它使得视图变得代码中心化,这可能违背了MVC概念中让视图尽可能愚笨的理念。例如,Spark的目标是“允许HTML主导流程,代码无缝融入其中”。因此,具体的好处在于更容易遵循MVC的精神。
<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>

如果上述只是语法糖,那么ASP.NET MVC本身就是建立在ASP.NET Web Forms之上的语法糖。

在您的示例中,p.Name 仍然被注入到视图中(或多或少),就像在 asp.net mvc 的标准引擎中一样,只是使用 ${} 而不是尖括号和百分号。这有什么不同呢? - Robert Harvey
更准确地说,ASP.NET视图只是语法糖,而不是整个ASP.NET MVC。 ASP.NET MVC包含的内容远不止这些。 - Robert Harvey
其实,我认为我比nHaml更喜欢这个。它看起来仍然像ASP.NET MVC,但将代码语句折叠到声明式HTML属性中。所有的C#都支持这种方式吗? :) - Robert Harvey
几乎可以使用CSharp代码来生成输出。任何辅助方法、对象属性或计算为非void值的表达式都可以使用。http://sparkviewengine.com/book/export/html/4 - bzlm
"<ul if="products.Any()">" 不就是 C# 代码的语法糖吗? - Robert Harvey
2
糖分含量高并不一定只是空热量,更重要的是每个元素的作用域和if语句的范围都与元素的开始和结束标签相对应。如果你的HTML格式正确,那么你的代码也是规范的,避免了<% } } %>这类麻烦。当然还有更多特性需要你去深入了解,但以上七行已经足够给你留下一个不错的第一印象了。 - loudej

2

从nhaml视角出发

  • 让视图更加简洁

Nhaml视图(274字符)

%h2= ViewData.CategoryName
%ul
  - foreach (var product in ViewData.Products)
    %li
      = product.ProductName 
      .editlink
        = Html.ActionLink("Edit", new { Action="Edit" ID=product.ProductID })
= Html.ActionLink("Add New Product", new { Action="New" })

aspx view (665 chars)

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="List.aspx" Inherits="MvcApplication5.Views.Products.List" Title="Products" %>
<asp:Content ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
  <h2><%= ViewData.CategoryName %></h2>
  <ul>
    <% foreach (var product in ViewData.Products) { %>
      <li>
        <%= product.ProductName %> 
        <div class="editlink">
          (<%= Html.ActionLink("Edit", new { Action="Edit", ID=product.ProductID })%>)
        </div>
      </li>
    <% } %>
  </ul>
  <%= Html.ActionLink("Add New Product", new { Action="New" }) %>
</asp:Content>

它通过一系列速记字符来实现。完整列表请参见此处[http://code.google.com/p/nhaml/wiki/NHamlLanguageReference]
  • 局部和布局
最好查看这里[http://code.google.com/p/nhaml/wiki/PartialsAndLayouts]
  • 默认情况下(通过配置),对所有内容进行html编码以避免XSS

  • XHTML兼容输出

从Spark的角度来看
  • 嵌入代码到xml标记和自定义代码标记中,可以用于执行程序化操作。这使得Spark可以将上下文切换最小化,对于nhaml和aspx都是如此。
例如,这个Spark:
<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>

若想使用aspx和nhaml来执行if..else语句,你需要进行上下文切换。

参考资料

[http://code.google.com/p/nhaml/wiki/NHamlLanguageReference]

[http://sparkviewengine.com/documentation/syntax]


确实看起来更简洁。然而,需要缩进的要求只有那些使用F#开发的人才会熟悉。 - Robert Harvey
在 nHaml 中如何指定继承?在默认视图引擎中,它被指定为 Inherits="MvcApplication5.Views.Products.List"。 - Robert Harvey
此外,您提供的视图示例似乎是从一个ASP.NET页面派生的。其中一些字符,例如AutoEventWireUp、CodeBehind和Runat=Server是多余的(它们在ASP.NET MVC中并不使用)。 - Robert Harvey

0

是的,请查看.NET的HTML生成器?

您希望在普通C#代码中具有相同的重构能力。它是代码,因此您希望能够以相同的方式对其进行结构化。使用继承、组合、参数、循环、递归等。


0
“语法糖”是以何种方式存在的?让你学习另一种语法吗?不是的。这些引擎对于从其他平台迁移的开发人员非常有用,可以使他们的生活更加轻松。

1
我认为Rob所说的是那些在其他框架/平台中使用了MVC模式的人。例如,在Ruby on Rails中使用Haml,在Castle Monorail中使用NVelocity等。他们可以过渡到与他们习惯的视图引擎类似的东西。 - Simon
我觉得Rob已经说明了我的观点。对于像我这样已经熟悉ASP.NET MVC的人来说,这不会带来任何好处。 - Robert Harvey
但我可以看出,对于那些已经熟悉语法的人来说,它会非常有价值。 - Robert Harvey
使用StringTemplate视图引擎对于任何想要严格执行模型/视图分离特别是MVC模式的人来说非常有用。这并不一定是关于转换或迁移的问题。http://websitelogic.net/articles/MVC/stringtemplate-viewengine-asp-net-mvc/ - bzlm
其他替代视图引擎中是否也可以声称严格的模型/视图分离?StringTemplate中的代码可能相当漂亮,但它仍然必须在模板中打洞以让数据通过。 - Robert Harvey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接