I was searching for a way to pass ViewDataDictionary to a partial view in ASP.NET MVC that I came to this syntax:
new ViewDataDictionary { { "Name", "Value" } }
I'm a bit confused about the initializer syntax here. can anyone explain it to me?
ViewData is a dictionary of objects that are stored and retrieved using strings as keys. It is used to transfer data from Controller to View. Since ViewData is a dictionary, it contains key-value pairs where each key must be a string. ViewData only transfers data from controller to view, not vice-versa.
ViewBag is also similar to ViewData. It is used to transfer data from Controller to View. It is a type of Dynamic object, that means you can add new fields to viewbag dynamically and access these fields in the View. You need to initialize the object of viewbag at the time of creating new fields.
ViewData contains key-value pairs which means each key must be a string in a dictionary. The only limitation of ViewData is, it can transfer data from controller to view. It can not transfer in any other way and it is valid only during the current request.
You can now access ViewData["students"] in the view, as shown below. Above, we retrieve the value using ViewData["students"] and typecast it to an appropriate data type. You can also add KeyValuePair objects into the ViewData, as shown below. ViewData and ViewBag both use the same dictionary internally.
ViewDataDictionary
implements IDictionary<string, object>
.
IDictionary<string, object>
is essentially a collection of KeyValuePair<string, object>
.
Your ViewDataDictionary
initializer (outer curly braces) contains another set of curly braces that represents a KeyValuePair<string, object>
initializer.
The reason this is possible is explained in this answer.
You can Add
multiple items by comma separating the KeyValuePair<string, object>
initializers:
var data = new ViewDataDictionary { { "Name", "Value" }, { "Name2", "Value2" } };
Is the same as:
var data = new ViewDataDictionary { new KeyValuePair<string, object>("Name", "Value"), new KeyValuePair<string, object>("Name2", "Value2") };
Essentially, the inner curly braces are nice syntax for initializing KeyValuePair<string, object>
objects.
I solved this using an extension method:
/// <summary> /// Use this extension method to create a dictionary or objects /// keyed by their property name from a given container object /// </summary> /// <param name="o">Anonymous name value pair object</param> /// <returns></returns> public static Dictionary<string, object> ToDictionary(this object o) { var dictionary = new Dictionary<string, object>(); foreach (var propertyInfo in o.GetType().GetProperties()) { if (propertyInfo.GetIndexParameters().Length == 0) { dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(o, null)); } } return dictionary; }
And an Html Helper extension:
/// <summary> /// When viewData is null, we just return null. Otherwise, we /// convert the viewData collection to a ViewDataDictionary /// </summary> /// <param name="htmlHelper">HtmlHelper provided by view</param> /// <param name="viewData">Anonymous view data object</param> /// <returns></returns> public static ViewDataDictionary vd(this HtmlHelper htmlHelper, object viewData) { if (viewData == null) return null; IDictionary<string, object> dict = viewData.ToDictionary(); //We build the ViewDataDictionary from scratch, because the // object parameter constructor for ViewDataDictionary doesn't // seem to work... ViewDataDictionary vd = new ViewDataDictionary(); foreach (var item in dict) { vd[item.Key] = item.Value; } return vd; }
Use from a razor file as:
@Html.Partial("~/Some/Path.cshtml", Model, Html.vd(new { SomeKey = SomeObj }))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With