如何用剃刀视图引擎简洁地创build可选的HTML属性?

我正在寻找一种方式来编写下面的代码行(可能是5)的代码。 我想我可以做所选类的相同的东西,但这个剃刀的语法看起来不漂亮。

<ul> @foreach (var mi in Model.MenuItems) { <li@(mi.Selected?" class=\"selected\"":null)> @if (string.IsNullOrEmpty(mi.Title)) { <a href="@mi.Href">@mi.Text</a> } else { <a href="@mi.Href" title="@mi.Title">@mi.Text</a> } </li> } </ul> 

在ASP.NET MVC 4中修复

http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx

有条件的属性呈现

如果你有一个可能为空的属性,在过去你需要做一个空检查,以避免写出一个空属性,如下所示:

 <div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div> 

现在Razor能够自动处理,所以你可以写出属性。 如果为空,则该属性不写入:

 <div class="@myClass">Content</div> 

所以如果@myClass为null,则输出就是这样的:

 <div>Content</div> 

我想出了一个可链式的HtmlAttribute类和一些Html扩展方法来允许下面的Razor语法:

 <ul> @foreach (var mi in items) { <li @Html.Css("selected", mi.Selected)> <a href="@mi.Href" @Html.Attr("title", mi.Title)>@mi.Text</a> </li> } </ul> 

这里是HtmlAttribute类:

 public class HtmlAttribute : IHtmlString { private string _InternalValue = String.Empty; private string _Seperator; public string Name { get; set; } public string Value { get; set; } public bool Condition { get; set; } public HtmlAttribute(string name) : this(name, null) { } public HtmlAttribute( string name, string seperator ) { Name = name; _Seperator = seperator ?? " "; } public HtmlAttribute Add(string value) { return Add(value, true); } public HtmlAttribute Add(string value, bool condition) { if (!String.IsNullOrWhiteSpace(value) && condition) _InternalValue += value + _Seperator; return this; } public string ToHtmlString() { if (!String.IsNullOrWhiteSpace(_InternalValue)) _InternalValue = String.Format("{0}=\"{1}\"", Name, _InternalValue.Substring(0, _InternalValue.Length - _Seperator.Length)); return _InternalValue; } } 

其他信息:“分隔符”用于将属性的多个值链接在一起。 这可以用于多个css类名(使用空格),也可以使用String.Empty来build立依赖于多个条件的值(使用.Add()方法)

这里是Html扩展的帮手方法:

 public static class Extensions { public static HtmlAttribute Css(this HtmlHelper html, string value) { return Css(html, value, true); } public static HtmlAttribute Css(this HtmlHelper html, string value, bool condition) { return Css(html, null, value, condition); } public static HtmlAttribute Css(this HtmlHelper html, string seperator, string value, bool condition) { return new HtmlAttribute("class", seperator).Add(value, condition); } public static HtmlAttribute Attr(this HtmlHelper html, string name, string value) { return Attr(html, name, value, true); } public static HtmlAttribute Attr(this HtmlHelper html, string name, string value, bool condition) { return Attr(html, name, null, value, condition); } public static HtmlAttribute Attr(this HtmlHelper html, string name, string seperator, string value, bool condition) { return new HtmlAttribute(name, seperator).Add(value, condition); } } 

让我知道他们是否有用。

谢谢,

背风处

 <ul> @foreach (var mi in Model.MenuItems) { <li@(mi.Selected?" class=\"selected\"":null)> <a href="@mi.Href" @{if(!string.IsNullOrEmpty(mi.Title)) { <text>title="@mi.Title"</text>} }>@mi.Text</a> </li> } </ul> 

我没有testing过,但它parsing正确。

这将是一个很好的自定义HTML助手的候选人:

 public static class HtmlExtensions { public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper, MenuItem mi) { var li = new TagBuilder("li"); if (mi.Selected) { li.AddCssClass("selected"); } var a = new TagBuilder("a"); a.MergeAttribute("href", mi.Href); if (!string.IsNullOrEmpty(mi.Title)) { a.MergeAttribute("title", mi.Title); } a.SetInnerText(mi.Text); return MvcHtmlString.Create(li.ToString()); } } 

并在你看来:

 <ul> @foreach (var mi in Model.MenuItems) { @Html.MenuItem(mi) } </ul> 

或使用DisplayTemplates你甚至不需要写一个循环:

 <ul> @Html.DisplayFor(x => x.MenuItems) </ul> 
 <ul> @foreach (var mi in Model.MenuItems) { <li@(Html.Raw((mi.Selected ? " class=\"selected\"" : null))> <a href="@mi.Href">@mi.Text</a> </li> } </ul> 

如果值为null ,则Razor不会呈现class属性

 <a href="#nolink" class="@(categoryId == null ? "submenu-active": null)">All</a> 

对于多个类的情况,我使用这个简单的扩展方法:

 public static MvcHtmlString If(this string text, bool condition) { return new MvcHtmlString(condition ? text : string.Empty); } 

并认为:

 <div class="menuitem @("active".If(Model.Active))"> 

沟刀片和使用Spark视图引擎。 ;)

看看simpiler可选的HTML属性在这里有多less工作http://sparkviewengine.com/documentation/expressions#Conditionalattributeoutput

这真的很简单,干净:

 <p @(cssClass != null) ? { class="@cssClass" }> Stuff and whatnot... </p>