Can EditorHelper use ViewBag to transfer data to the corresponding template?

I observed a somewhat peculiar behavior when overwriting the Object.cshtm template. Object.cshtm Model properties and sends them to the appropriate template for rendering.

 foreach (var prop in ViewData.ModelMetadata.Properties) { @Html.Editor(prop.PropertyName, "MyCustomTemplateCollection" + prop.TemplateHint) //TemplateHint set by custom attributes } 

Everything works well: the template switches to the appropriate type template and inside those I can access the Metadata properties:

 string name = ViewData.ModelMetadata.PropertyName; string controllerName = ViewData.ModelMetadata.ContainerType.Name; //render property accordingly (using the property information) 

However, if for some reason the ViewBag contains a (dynamic) property with the same name as one of the Model properties, ModelMetadata not fully generated; at least the ModelMetadata properties described above are set to null . For example, if in my controller I set ViewBag.ProductName = myModel.ProductName; when the ProductName property falls into the corresponding template, the metadata does not contain the expected values.

Decision quite simple: if for some reason a property should be saved in the ViewBag , it should be saved under a different name.

My question is: how do I pass EditorHelper data to templates? I would not expect ViewData and ViewBag "share" such information. Validation with QuickWatch I can see in Non-Public members properties of the ViewBag a ViewData , which looks the same as, say, a public ViewData object. Why aren't they completely independent?

+6
source share
1 answer

Your question has a very simple answer:

ViewBag is a dynamic wrapper for ViewData . They are actually one and the same. Everything that you put in ViewData is also in ViewBag and vice versa.

You can see the implementation of DynamicViewDataDictionary (this is what the ViewBag is an instance of) here . As you can see, it simply contains an internal reference to the ViewDataDictionary , which it wraps and delegates access to the properties of dictionary elements.

So, when the environment passes the ViewData to the template with a specific key, and you assign the ViewBag property with the appropriate name, only one can win.

The other side of the coin, which, in my opinion, is more relevant, is that the static ModelMetadata methods that are responsible for checking ViewData metadata, first - before considering the metadata of the model object.

So, if you assign ViewBag properties (and - by association - ViewData ), these are properties that will be mapped to the expression you passed to the template and they will not have specific metadata, such as those provided by data annotations for the model class.

+1
source

All Articles