如何在MVC htmlAttribute中设置禁用

使用HTML Helper时,根据条件设置属性的最佳方法是什么。 例如

  m.FirstName, new {@class='contactDetails'}%>   m.FirstName, new {@class='contactDetails', disabled = true}%>  

必须有一种更好的方法来以编程方式向匿名类型添加一个额外的KeyPair吗? 不能用

 new { .... disabled = Page.User.IsInRole("administrator") ... } 

因为浏览器将任何禁用的属性值视为禁用输入

我建议你使用mvccontrib.FluentHtml。

你可以做这样的事情

  <%=this.TextBox(m=>m.FirstNam ).Disabled(Page.User.IsInRole("administrator"))%> 

它对我也有用……

 <%: Html.DropDownList("SportID", (SelectList)ViewData["SportsSelectList"], "-- Select --", new { @disabled = "disabled", @readonly = "readonly" })%> <%= Html.CheckBoxFor(model => model.IsActive, new { @disabled = "disabled", @readonly = "readonly" })%> 

Page.User.IsInRole(“管理员”)? null:new {disabled =“disabled”}

使用@SLaks建议使用Extension方法,并使用Jeremiah Clark的示例扩展方法我已经编写了一个扩展方法,所以我现在可以做

 Html.TextBoxFor(m => m.FirstName,new{class='contactDetails', ...},Page.User.IsInRole("administrator")); 

不确定是否有更好的方法

 public static class InputExtensions { public static IDictionary TurnObjectIntoDictionary(object data) { var attr = BindingFlags.Public | BindingFlags.Instance; var dict = new Dictionary(); if (data == null) return dict; foreach (var property in data.GetType().GetProperties(attr)) { if (property.CanRead) { dict.Add(property.Name, property.GetValue(data, null)); } } return dict; } public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes, bool disabled) { IDictionary values = TurnObjectIntoDictionary(htmlAttributes); if (disabled) values.Add("disabled","true"); return htmlHelper.TextBoxFor(expression, values); } public static MvcHtmlString TextAreaFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes, bool disabled) { IDictionary values = TurnObjectIntoDictionary(htmlAttributes); if (disabled) values.Add("disabled", "true"); return htmlHelper.TextAreaFor(expression, values); } public static MvcHtmlString CheckBoxFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes, bool disabled) { IDictionary values = TurnObjectIntoDictionary(htmlAttributes); if (disabled) values.Add("disabled", "true"); return htmlHelper.CheckBoxFor(expression, values); } } 

您需要传递Dictionary ,并在if语句中添加disabled键。

我建议对扩展方法进行重载,该方法接受bool disabled参数,并将其添加到从attributes参数创建的RouteValueDictionary ,如果它是true 。 (如果它是false ,你也可以从RouteValueDictionary删除disabled条目,而不是取另一个参数)

您可能需要考虑使用新的TextBox方法编写自己的HtmlHelper Extension类:

 public static class HtmlHelperExtensions { public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression> expression, string cssClass, bool disabled) { return disabled ? Html.TextBoxFor(expression, new {@class=cssClass, disabled="disabled"}) : Html.TextBoxFor(expression, new {@class=cssClass}) } } 

now(如果这个新类在同一名称空间中,或者您已将新名称空间导入页眉,或者在web.config的pages部分中),则可以在aspx页面上执行此操作:

 <%=Html.TextBoxFor(m => m.FirstName, "contactDetails", Page.User.IsInRole("administrator")) %> 

在Object上创建了一个扩展方法,它将创建输入对象的副本,排除任何null属性,并将其全部作为字典返回,使其易于在MVC HtmlHelpers中使用:

 public static Dictionary StripAnonymousNulls(this object attributes) { var ret = new Dictionary(); foreach (var prop in attributes.GetType().GetProperties()) { var val = prop.GetValue(attributes, null); if (val != null) ret.Add(prop.Name, val); } return ret; } 

不确定两次反映属性的性能影响,并且不太喜欢扩展方法的名称,但似乎做得很好……

 new { @class = "contactDetails", disabled = Page.User.IsInRole("administrator") ? "true" : null }.StripAnonymousNulls() 

您也可以这样定义此参数:

 Page.User.IsInRole("administrator") ? (object)new { @class='contactDetails'} : (object)new { @class='contactDetails', disabled = true}