Asp.net-Mvc

EditorFor() 和 additionalViewData:如何在幫助類中添加數據?

  • November 7, 2014

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());
   }

更新當我將匿名對象轉換為 aDictionary<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})

引用自:https://stackoverflow.com/questions/6296583