Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shorthand for creating a ViewDataDictionary with both a model and ViewData items?

Is there any way to create a ViewDataDictionary with a model and additional properties with a single line of code. I am trying to make a RenderPartial call to a strongly-typed view while assembling both the model and some extra display configuration properties without explicitly assembling the ViewDataDictionary across multiple lines. It seems like it would be possible given the RenderPartial overload taking both a model object and a ViewDataDictionary but it looks like it simply ignores the ViewDataDictionary whenever they are both populated.

// FAIL: This will result in ViewData being a ViewDataDictionary // where Model = MyModelObject and there are no other parameters available. this.Html.RenderPartial("SomePartialView", MyModelObject, new ViewDataDictionary(new { SomeDisplayParameter = true })); 

I found someone else with the same problem, but their solution is the same multi-line concept I found: create a discrete ViewDataDictionary with the model, add the new parameter(s) and use it in the RenderPartial call.

var SomeViewData = new ViewDataDictionary(MyModelObject); SomeViewData.Add("SomeDisplayParameter", true); this.Html.RenderPartial("SomePartialView", SomeViewData); 

I can always wrap that logic into a ChainedAdd method that returns a duplicate dictionary with the new element added but it just seems like I am missing some way of creating a ViewDataDictionary that would do this for me (and that is a bit more overhead than I was hoping for).

this.Html.RenderPartial("SomePartialView", new ViewDataDictionary(MyModelObject).ChainedAdd("SomeDisplayParameter", true));  public static ViewDataDictionaryExtensions {     public static ViewDataDictionary ChainedAdd(this ViewDataDictionary source, string key, object value) {         return source.ChainedAdd(new KeyValuePair<string,object>(key, value));     }     public static ViewDataDictionary ChainedAdd(this ViewDataDictionary source, KeyValuePair<string, object> keyAndValue) {         ViewDataDictionary NewDictionary = new ViewDataDictionary(source);         NewDictionary.Add(keyAndValue);         return NewDictionary;     } } 

As well, trying to assemble a ViewDataDictionary with an explicit Model and ModelState simply causes a compilation error because the ModelState is read-only.

// FAIL: Compilation error this.Html.RenderPartial("SomePartialView", new ViewDataDictionary { Model = MyModelObject, ModelState = new ViewDataDictionary( new { SomeDisplayParameter = true }}); 

ANSWER(S): It looks like Craig and I ended up finding two separate syntaxes that will get the job done. I am definitely biased in this case, but I like the idea of setting the model first and "decorating" it afterwards.

new ViewDataDictionary(MyModelObject) { { "SomeDisplayParameter", true }, { "SomeOtherParameter", 3 }, { "SomeThirdParameter", "red" } };  new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})     { Model = MyModelObject }; 

Of course, I would still be spinning my wheels without his [eventually spot-on] answer, so, circle gets the square.

like image 540
patridge Avatar asked Mar 03 '09 20:03

patridge


People also ask

How to pass data from View to Controller using ViewData?

ViewData itself cannot be used to send data from View to Controller and hence we need to make use of Form and Hidden Field in order to pass data from View to Controller in ASP.Net MVC Razor.

How to assign Value to ViewData in Controller?

Create a hidden input <input type="hidden" name="selectedTabIndex"/> and set the value with javascript prior to POST . The controller can extract this value from the Form parameters, or it can be autopopulated in the Action method if the method contains a parameter matching the input name.

What kind of object is ViewData?

ViewData is a ViewDataDictionary object accessed through string keys. String data can be stored and used directly without the need for a cast, but you must cast other ViewData object values to specific types when you extract them.


1 Answers

Use an object initializer and collection initializers:

new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})     {         Model = MyModelObject     } 

The inner ViewDataDictionary gets its collection initialized, then this populates the "real" ViewDataDictionary using the constructor overload which takes ViewDataDictionary instead of object. Finally, the object initializer sets the model.

Then just pass the whole thing without setting MyModelObject separately:

this.Html.RenderPartial("SomePartialView", null,      new ViewDataDictionary(new ViewDataDictionary() { {"SomeDisplayParameter", true }})         { Model = MyModelObject }); 
like image 182
Craig Stuntz Avatar answered Sep 20 '22 14:09

Craig Stuntz