EditorFor() 和 additionalViewData:如何在幫助類中添加數據?
EditorFor() 可以接受一個
object additionalViewData參數,典型的填充方法如下:
EditorFor(model => model.PropertyName, new { myKey = "myValue" })如何在自定義 HTML Helper 中檢查 AdditionalViewData 的內容、添加或附加到鍵的現有值等?
我試過這些方法:
- 轉換為
Dictionary<string, object>()並添加/附加值:不起作用,因為它看起來像 MVC 中 EditorFor 的實現使用 new RouteValueDictionary(additionalViewData) 將字典嵌入字典中new RouteValueDictionary(additionalViewData)使用但具有與上述相同(或非常相似)的問題轉換為 RouteValueDictionary我也對“你做錯了”持開放態度——也許我錯過了一種更簡單的方法。請記住,我要做的是編寫一個可重用的 HTML 幫助程序,並將一些值添加到 AdditionalViewData 以供自定義視圖使用。一些值依賴於屬性的元數據,所以它並不像使用一堆不同的模板那麼容易。
更新我正在做的例子:
public static MvcHtmlString myNullableBooleanFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> choice, string templateName, object additionalViewData) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(choice, htmlHelper.ViewData); /* here need to add to additionalViewData some key values among them: { propertyName, metadata.PropertyName } */ StringBuilder sb = new StringBuilder(); sb.AppendLine(htmlHelper.EditorFor(choice, templateName, additionalViewData).ToString()); MvcHtmlString validation = htmlHelper.ValidationMessageFor(choice); if (validation != null) sb.AppendLine(validation.ToString()); return new MvcHtmlString(sb.ToString()); }更新當我將匿名對象轉換為 a
Dictionary<string, object>()並將該字典傳遞給時發生的情況EditorFor():我在 Razor 視圖中設置了一個斷點並檢查了 ViewData。似乎傳入的字典
EditorFor()被放在另一個里面Dictionary<string, object>()。在“即時視窗”中,ViewData 如下所示:ViewData.Keys Count = 4 [0]: "Comparer" [1]: "Count" [2]: "Keys" [3]: "Values"看看字典中如何包含字典的內容?是的,實際數據在那個內部字典中,但不出所料,這不起作用。
增加了賞金。
如果我理解正確,您正在嘗試迭代匿名類型的屬性。如果是這樣:如何在 C# 中迭代匿名對象的屬性?
[編輯] 好的,不僅如此。這現在真的很困擾我,因為我喜歡 C#,它不會讓我做 Python 所做的事情,我也喜歡它。所以這是一個解決方案,如果您使用的是 C# 4,但它很混亂,並且可以解決我遇到的類似問題,但可能不完全適合您:
// Assume you've created a class to hold commonly used additional view data // called MyAdditionalViewData. I would create an inheritance hierarchy to // contain situation-specific (area-specific, in my case) additionalViewData. class MyAdditionalViewData { public string Name { get; set; } public string Sound { get; set; } } /* In your views */ // Pass an instance of this class in the call to your HTML Helper EditorFor(model => model.PropertyName, new { adv = new MyAdditionalViewData { Name = "Cow", Sound = "Moo" } }) ; /* In your HTML helper */ // Here's the C# 4 part that makes this work. dynamic bovine = new ExpandoObject(); // Copy values var adv = x.adv; if (adv.Name != null) bovine.Name = adv.Name; if (adv.Sound != null) bovine.Sound = adv.Sound; // Additional stuff bovine.Food = "Grass"; bovine.Contents = "Burgers"; // When the MVC framework converts this to a route value dictionary // you'll get a proper object, not a dictionary within a dictionary var dict = new RouteValueDictionary(bovine);必須有更好的方法。
就我而言,我有一個布爾欄位的編輯器,我想成為一個是/否收音機。我使用 AdditionalViewData 屬性來設置是/否的文本進行本地化。似乎對我很有用!
這是我的自定義編輯器的程式碼:
@model bool? @{ var yes = ViewBag.TrueText ?? @Resources.WebSiteLocalizations.Yes; var no = ViewBag.FalseText ?? @Resources.WebSiteLocalizations.No; } <div class="title"> @Html.LabelFor(model => model) @Html.RequiredFor(model => model) </div> <div class="editor-field"> @Html.RadioButton("", "True", (Model.HasValue && Model.Value))@yes <br /> @Html.RadioButton("", "False", (Model.HasValue && Model.Value == false))@no <br /> @Html.ValidationMessageFor(model => model) </div> @Html.DescriptionFor(model => model)這是您如何呼叫此自定義 EditorFor:
@Html.EditorFor(model => model.IsActive, new {TrueText = @Resources.WebSiteLocalizations.Active, FalseText = @Resources.WebSiteLocalizations.InActive})