ASP.NET MVC中EditorFor()的Html属性
为什么我不能将html属性传递给EditorFor()
? 例如;
<%= Html.EditorFor(model => model.Control.PeriodType, new { disabled = "disabled", readonly = "readonly" }) %>
我不想使用元数据
更新 :解决scheme是从视图中调用这个:
<%=Html.EditorFor( model => model.Control.PeriodEndDate, new {Modifiable=model.Control.PeriodEndDateModifiable})%>
并在我的自定义EditorTemplates / String.ascx中使用ViewData["Modifiable"]
,其中我有一些视图逻辑,确定是否添加只读和/或禁用属性到input传递到EditorFor()
的匿名对象是一个名为additionalViewData
的参数和其属性将传递给ViewData
集合中的编辑器模板。
EditorFor
对元数据的工作,所以如果你想添加HTML属性,你可以随时做到这一点 。 另一种select是简单地写一个自定义模板并使用TextBoxFor
:
<%= Html.TextBoxFor(model => model.Control.PeriodType, new { disabled = "disabled", @readonly = "readonly" }) %>
更新 MVC 5.1现在直接支持以下方法,所以它也适用于内置编辑器。 http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features (这是一个伟大的思想相似或他们阅读我的答案:)
结束更新
如果您使用自己的编辑器模板或者使用MVC 5.1,现在直接支持内置编辑器的以下方法。
@Html.EditorFor(modelItem => item.YourProperty, new { htmlAttributes = new { @class="verificationStatusSelect", style = "Width:50px" } })
然后在您的模板(MVC 5.1简单types不需要)
@Html.TextBoxFor(m => m, ViewData["htmlAttributes"])
从MVC 5.1开始,您现在可以执行以下操作:
@Html.EditorFor(model => model, new { htmlAttributes = new { @class = "form-control" }, })
http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features
现在ASP.Net MVC 5.1得到了内置的支持。
从发行说明
我们现在允许在EditorFor中传递HTML属性作为匿名对象。
例如:
@Html.EditorFor(model => model, new { htmlAttributes = new { @class = "form-control" }, })
这里是MVC 5.1 EditorFor的html属性的VB.Net代码语法
@Html.EditorFor(Function(x) x.myStringProp, New With {.htmlAttributes = New With {.class = "myCssClass", .maxlength="30"}}))
为什么不使用
@Html.DisplayFor(model => model.Control.PeriodType)
如果你不想使用元数据,你可以使用[UIHint("PeriodType")]
属性来装饰属性,或者如果它是一个复杂的types,你不必装饰任何东西。 然后,EditorFor将在EditorTemplates文件夹中查找PeriodType.aspx或ascx文件,然后使用它。
你仍然可以使用EditorFor。 只需传递样式/无论哪个html属性ViewData。
@Html.EditorFor(model => model.YourProperty, new { style = "Width:50px" })
由于EditorFor使用模板进行渲染,因此可以覆盖属性的默认模板,只需将style属性作为ViewData传递即可。
所以你的EditorTemplate会喜欢以下内容:
@inherits System.Web.Mvc.WebViewPage<object> @Html.TextBoxFor(m => m, new { @class = "text ui-widget-content", style=ViewData["style"] })
Html.TextBoxFor(model => model.Control.PeriodType, new { @class="text-box single-line"})
你可以这样使用; 与Html.EditorFor
相同的输出,你可以添加你的html属性
我一直在荆棘与今天的checkbox绑定到一个可空布尔,因为我不能改变我的模型(不是我的代码),我不得不想出一个更好的方式来处理这个问题。 这有点暴躁,但它应该适用于我可能遇到的99%的情况。 你显然不得不为每个inputtypes做一些有效属性的手工填充,但是我想我已经把所有的这些填入了checkbox。
在我的Boolean.cshtml编辑器模板中:
@model bool? @{ var attribs = new Dictionary<string, object>(); var validAttribs = new string[] {"style", "class", "checked", "@class", "classname","id", "required", "value", "disabled", "readonly", "accesskey", "lang", "tabindex", "title", "onblur", "onfocus", "onclick", "onchange", "ondblclick", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onselect"}; foreach (var item in ViewData) { if (item.Key.ToLower().IndexOf("data_") == 0 || item.Key.ToLower().IndexOf("aria_") == 0) { attribs.Add(item.Key.Replace('_', '-'), item.Value); } else { if (validAttribs.Contains(item.Key.ToLower())) { attribs.Add(item.Key, item.Value); } } } } @Html.CheckBox("", Model.GetValueOrDefault(), attribs)
只需在Views / Shared / EditorTemplates / MyTypeEditor.vbhtml中为types创build自己的模板
@ModelType MyType @ModelType MyType @Code Dim name As String = ViewData("ControlId") If String.IsNullOrEmpty(name) Then name = "MyTypeEditor" End If End Code ' Mark-up for MyType Editor @Html.TextBox(name, Model, New With {.style = "width:65px;background-color:yellow"})
使用模型属性从视图中调用编辑器:
@Html.EditorFor(Function(m) m.MyTypeProperty, "MyTypeEditor", New {.ControlId = "uniqueId"})
赦免VB语法。 这就是我们如何滚动。
在我的情况下,我试图创build一个可以接收附加属性的HTML5数字input编辑器模板。 一个更简洁的方法是编写自己的HTML Helper,但是因为我已经有了.ascx模板,所以我采用了这种方法:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <input id="<%= Regex.Replace(ViewData.TemplateInfo.GetFullHtmlFieldId(""), @"[\[\]]", "_") %>" name="<%= ViewData.TemplateInfo.HtmlFieldPrefix %>" type="number" value="<%= ViewData.TemplateInfo.FormattedModelValue %>" <% if (ViewData["attributes"] != null) { Dictionary<string, string> attributes = (Dictionary<string, string>)ViewData["attributes"]; foreach (string attributeName in attributes.Keys){%> <%= String.Format(" {0}=\"{1}\"", attributeName, attributes[attributeName])%> <% } } %> />
这个丑陋的位创build一个数字types的input,并查找关键“属性”的ViewData词典。 它将迭代字典,将其键/值对添加为属性。 在ID属性中的正则expression式是不相关的,因为在集合中使用时, GetFullHtmlFieldId()
返回一个包含方括号[]
的ID,它通常会作为下划线转义。
这个模板是这样调用的:
Html.EditorFor(m => m.Quantity, "NumberField", new { attributes = new Dictionary<string, string>() { { "class", "txtQuantity" } } }
详细,但它的作品。 您可以使用模板中的reflection来使用属性名称作为属性名称,而不是使用字典。
在控制器中使用ViewData
设置条件
ViewData["Modifiable"] = model.recProcessed;
然后在编辑器模板中使用这个viewdata来设置控件的html属性
@Html.RadioButton(prefix, li.Value, li.Selected, @ViewData["Modifiable"].ToString().ToLower() == "true" ? (object)new { @id = li.Value, @disabled = "disabled" } : new { @id = li.Value })
MVC 5.1及更高版本的解决scheme(将合并本地HtmlAttributes并在EditorTemplates中定义):
共享\ EditorTemplates \ String.cshtml:
@Html.TextBoxFor(model => model, new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark }.ToExpando().MergeHtmlAttributes(ViewData["htmlAttributes"].ToExpando()))
扩展:
public static IDictionary<string, object> MergeHtmlAttributes(this ExpandoObject source1, dynamic source2) { Condition.Requires(source1, "source1").IsNotNull().IsLongerThan(0); IDictionary<string, object> result = source2 == null ? new Dictionary<string, object>() : (IDictionary<string, object>) source2; var dictionary1 = (IDictionary<string, object>) source1; string[] commonKeys = result.Keys.Where(dictionary1.ContainsKey).ToArray(); foreach (var key in commonKeys) { result[key] = string.Format("{0} {1}", dictionary1[key], result[key]); } foreach (var item in dictionary1.Where(pair => !result.ContainsKey(pair.Key))) { result.Add(item); } return result; } public static ExpandoObject ToExpando(this object anonymousObject) { IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(anonymousObject); IDictionary<string, object> expando = new ExpandoObject(); foreach (var item in anonymousDictionary) expando.Add(item); return (ExpandoObject)expando; } public static bool HasProperty(this ExpandoObject expando, string key) { return ((IDictionary<string, object>)expando).ContainsKey(key); }
用法:
@Html.EditorFor(m => m.PromotionalCode, new { htmlAttributes = new { ng_model = "roomCtrl.searchRoomModel().promoCode" }})