2010-09-17 77 views
117

爲什麼我不能將html屬性傳遞給EditorFor()?例如;ASP.NET MVC中EditorFor()的Html屬性

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

我不想使用元數據

更新:解決的辦法是從視圖中調用這個:

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

和我的自定義EditorTemplates /字符串使用ViewData["Modifiable"]。 ascx其中我有一些視圖邏輯,用於確定是將只讀屬性還是禁用屬性添加到輸入 傳遞到EditorFor()的匿名對象是一個名爲的參數及其屬性傳遞給ViewData集合中的編輯器模板。

+18

嚴重的是,仍然在MVC3這個限制沒有意義,它真的很煩人。世界各地的人們正在花時間,用這些無聊的東西拉着頭髮。我將此發送給Microsoft Connect。 – 2012-09-21 14:14:30

+5

https://connect.microsoft.com/VisualStudio/feedback/details/764012/allow-htmlattributes-in-asp-net-mvc-editorfor – 2012-09-21 14:44:26

+3

它只是我,還是看起來像很多bs的東西應該太簡單了? – 2012-12-11 01:08:56

回答

94

EditorFor適用於元數據,所以如果你想添加html屬性你could always do it。另一種選擇是簡單地寫一個自定義模板,並使用TextBoxFor

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

元數據將不起作用,因爲html屬性取決於模型中的其他屬性,換句話說,域或viemodel邏輯應該確定html屬性而不是靜態元數據。或者我錯過了這一點,我可以動態設置元數據嗎? – 2010-09-17 13:05:51

+0

什麼是PeriodType?這不是一個簡單的屬性?如果它是一個複雜的對象,您可以通過在'〜/ Views/ControllerName/EditorTemplates/SomeType.ascx'中放置一個部分來定製整個模板,其中'SomeType'是'PeriodType'屬性的類型名稱。 – 2010-09-17 13:06:30

+0

你的建議代碼也意味着將整個模型傳遞給訪問特定屬性的部分模板,這意味着我對每個屬性都有一個部分? – 2010-09-17 13:06:45

2

如果你不想使用元數據,您可以使用一個[UIHint("PeriodType")]屬性裝飾的財產,或者如果它是一個複雜的類型,你不必裝飾任何東西。然後EditorFor將在EditorTemplates文件夾中查找PeriodType.aspx或ascx文件並使用它。

+0

謝謝,如果我的編輯器模板中的if/else只對某些字段是必需的,我可能會這樣做 – 2010-09-17 13:36:18

+0

雖然你說你不能更改模型(不是你的代碼) ,所以直接用UIHint裝飾不會是一種選擇。 – 2012-11-08 01:28:55

3

爲什麼不直接使用

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

其中一個原因是DisplayFor未呈現輸入,因此回發時丟失該值。 – ProfK 2012-04-25 06:11:42

+1

另一個原因是編輯器當前 - 但不總是鎖定的特定情況,並且您想要傳達數據可能是可編輯的 - 現在不是。 – Mir 2012-12-14 22:39:58

1
Html.TextBoxFor(model => model.Control.PeriodType, 
    new { @class="text-box single-line"}) 

你可以使用這樣的;與Html.EditorFor相同的輸出,你可以添加你的html屬性

+0

除了'TextBoxFor',忽略任何你可能試圖應用的'DisplayFormat'類型。 – 2012-12-11 00:57:00

1

我一直在荊棘與今天相同的問題綁定到一個可空的布爾複選框,因爲我不能改變我的模型(不是我的代碼)我不得不想出一個更好的方式來處理這個問題。這有點暴躁,但它應該適用於我可能遇到的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) 
+0

我添加了'Dictionary attribs = new Dictionary ();'和'attribs.Add(「tabindex」,「16」);'在這些'@()'塊之一中我的頁面頂部。然後,我在我的頁面上執行了@ Html.CheckBox(「IsActive」,Model.IsActive.HasValue?Model.IsActive:false,attribs),它給了我一個錯誤:''System.Web.Mvc.HtmlHelper '不包含'CheckBox'的定義,並且最好的擴展方法重載'System.Web.Mvc.InputExtensions.CheckBox(System.Web.Mvc.HtmlHelper,string.bool,object)'有一些無效參數」。 – vapcguy 2014-10-25 02:22:55

1

剛剛創建自己的模板在視圖/類型的共享/ 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"}) 

從您的視圖調用編輯器模型屬性:

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

赦免VB語法。這就是我們滾動的方式。

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"] }) 
91

更新 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" } }) 

然後在模板

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

這個新功能完美地解決了四年前問的原始問題。 – CoderSteve 2014-10-30 17:24:13

+1

如果不是像這樣的TextBoxFor和helpers我使用噸自定義編輯器模板,我不會說這是一個夢幻般的主意,將ViewData添加到他們每個人...... :( – Alexander 2016-05-26 11:05:42

38

由於MVC 5.1(不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

+0

上述鏈接已死亡。是在MVC 5.1,更多信息在這裏:http://www.asp.net/mvc/overview/releases/mvc51-release-notes#new-features – 2014-03-03 15:55:04

+1

謝謝,我修復了鏈接以及。 – vtforester 2014-03-03 23:42:07

+1

如何合併htmlAttributes ? – 2014-04-07 19:11:16

5

現在ASP.Net MVC 5.1得到了一個bui以支持它。

From Release Notes

We now allow passing in HTML attributes in EditorFor as an anonymous object.

例如:

@Html.EditorFor(model => model, 
       new { htmlAttributes = new { @class = "form-control" }, }) 
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" }}) 
+1

謝謝,這是有效的。除了所有的data_xxx屬性,我不得不用_替換_當把'source1'和'source2'作爲'IDictionary '。 我做了這個函數: 'private static IDictionary ToHtmlAttributesDictionary(this IEnumerable > dico){return dico.ToDictionary(s => s.Key.Replace('_',' - '),s => s.Value );}' – 2014-10-31 10:50:26

1

在我來說,我試圖創造一種可以接受的附加屬性的HTML5號碼輸入編輯模板。一個整齊的辦法是寫自己的HTML助手,但因爲我已經有我的.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])%> 
     <% } 
    } %> /> 

這醜陋位創建許多類型的輸入和查找一個ViewData字典與關鍵的「屬性」。它將遍歷字典,將其鍵/值對添加爲屬性。 ID屬性中的正則表達式不相關,因爲在集合中使用時,GetFullHtmlFieldId()返回一個包含方括號[]的ID,它通常會作爲下劃線轉義。

這個模板,然後調用這樣的:

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

冗長,但它的作品。您可以使用模板中的反射來將屬性名稱用作屬性名稱,而不是使用字典。

4

以下是在MVC 5.1的VB.Net代碼語法HTML屬性EditorFor

@Html.EditorFor(Function(x) x.myStringProp, New With {.htmlAttributes = New With {.class = "myCssClass", .maxlength="30"}})) 
1

設置在所述控制器使用ViewData條件

ViewData["Modifiable"] = model.recProcessed; 

然後,在使用此可視數據編輯器模板來設置控件的html屬性

@Html.RadioButton(prefix, li.Value, li.Selected, @ViewData["Modifiable"].ToString().ToLower() == "true" ? (object)new { @id = li.Value, @disabled = "disabled" } : new { @id = li.Value })