ASP.NET MVC中EditorFor()的Html属性

时间:2010-09-17 12:45:26

标签: html asp.net-mvc editorfor

为什么我不能将html属性传递给EditorFor()?例如;

<%= Html.EditorFor(model => model.Control.PeriodType, 
    new { disabled = "disabled", readonly = "readonly" }) %>

我不想使用元数据

更新:解决方案是从视图中调用它:

 <%=Html.EditorFor( model => model.Control.PeriodEndDate, new {Modifiable=model.Control.PeriodEndDateModifiable})%>

并在我的自定义EditorTemplates / String.ascx中使用ViewData["Modifiable"],其中我有一些视图逻辑,用于确定是否将readonly和/或disabled属性添加到输入 传递到EditorFor()的匿名对象是一个名为additionalViewData的参数,其属性将传递到ViewData集合中的编辑器模板。

14 个答案:

答案 0 :(得分:114)

更新 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中的简单类型不需要)

@Html.TextBoxFor(m => m, ViewData["htmlAttributes"])

答案 1 :(得分:96)

EditorFor适用于元数据,因此如果您想添加html属性could always do it。另一种选择是简单地编写自定义模板并使用TextBoxFor

<%= Html.TextBoxFor(model => model.Control.PeriodType, 
    new { disabled = "disabled", @readonly = "readonly" }) %>    

答案 2 :(得分:42)

从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

答案 3 :(得分:6)

现在 ASP.Net MVC 5.1 得到了内置的支持。

From Release Notes

  

我们现在允许在EditorFor中传递HTML属性作为匿名   对象

例如:

@Html.EditorFor(model => model, 
              new { htmlAttributes = new { @class = "form-control" }, })

答案 4 :(得分:4)

以下是MVC 5.1中 html属性的 VB.Net代码语法 EditorFor

warn = my_val >= max or my_val <= min unless max.nil? and min.nil?

答案 5 :(得分:3)

为什么不使用

@Html.DisplayFor(model => model.Control.PeriodType)

答案 6 :(得分:2)

如果您不想使用元数据,可以使用[UIHint("PeriodType")]属性来装饰属性,或者如果它是复杂类型,则不必装饰任何内容。然后,EditorFor将在EditorTemplates文件夹中查找PeriodType.aspx或ascx文件,并使用该文件。

答案 7 :(得分:2)

您仍然可以使用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"] })

答案 8 :(得分:1)

Html.TextBoxFor(model => model.Control.PeriodType, 
    new { @class="text-box single-line"})
你可以这样使用;与Html.EditorFor相同的输出,您可以添加您的html属性

答案 9 :(得分:1)

我今天一直在努力解决一个与可空的bool绑定的复选框,因为我不能改变我的模型(不是我的代码),我不得不想出一个更好的方法来处理它。这有点暴力,但它应该适用于我可能遇到的99%的情况。你显然必须为每种输入类型做一些有效属性的手动填充,但我想我已经将所有这些都用于复选框。

在我的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)

答案 10 :(得分:1)

只需在Views / Shared / EditorTemplates / MyTypeEditor.vbhtml中为类型创建自己的模板

@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"})

使用model属性从视图中调用编辑器:

@Html.EditorFor(Function(m) m.MyTypeProperty, "MyTypeEditor", New {.ControlId = "uniqueId"})

请原谅VB语法。这就是我们如何滚动。

答案 11 :(得分:1)

在我的情况下,我试图创建一个可以接收其他属性的HTML5号码输入编辑器模板。一个更简洁的方法是编写自己的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])%>
       <% }
   } %> />

这个丑陋的位创建一个数字类型输入,并使用键&#34;属性&#34;查找ViewData字典。它将遍历字典,将其键/值对添加为属性。 ID属性中的Regex是不相关的,因为在集合中使用时,GetFullHtmlFieldId()返回一个包含方括号[]的id,它通常会以下划线的形式转义。

然后调用此模板:

Html.EditorFor(m => m.Quantity, "NumberField", new { attributes = new Dictionary<string, string>() { { "class", "txtQuantity" } } }

详细,但它确实有效。您可以使用模板中的反射将属性名称用作属性名称,而不是使用字典。

答案 12 :(得分:1)

使用控制器中的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 })

答案 13 :(得分:0)

MVC 5.1及更高版本的解决方案(将合并本地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" }})