I am trying to implement a requirement that will allow me to change the state of an html control based on the users role or other business logic. For example some users should not be able to edit a certain model property or in some cases I do not even want the control to render to the html DOM.
Within the HTML helpers the Metadata can tell the helper whether or not to render a control or it can make it read-only/disabled. Rather than re-invent the wheel here I just want to use what is already in place by changing the metadata within an action filter based on logic at run time. I do not want this logic within my view and I do not want to have to create custom helpers for every single html control if I do not have to..
What I was trying to do was create an action filter to handle evaluating logic rules in my business layer and then make changes to the metadata for a given model.property.
The problem is that my modifications to the metadata do not seem to be making it to the view. It almost seems like my changes to the metadata within the action filter are not by reference so therefore I am not modifying the same instance that is used for the view?
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var trans = filterContext.Controller.ViewData.ModelMetadata.Properties.Where(e => e.PropertyName == "Transaction").FirstOrDefault();
trans.DisplayName = "Show FOO!";
}
What am I doing wrong?
You cannot change the
ModelMetadata.Propertiesvalues in a filter in fact you cannot change them at all.The problem is inside the built in
DataAnnotationsModelMetadataProvider(to be preciseAssociatedMetadataProvider‘sGetMetadataForPropertiesmethod) namelly theModelMetadata.Propertiesgets regenerated from the attributes every time you iterate over it.So the items inside the
ModelMetadata.Propertiescollection are immutable.You can check it with debugging:
The
trans1andtrans2will be different instances (you can check their hashcode) sotrans2displayname will be the original displayname not “Show FOO!”.So you need to Extend/Write the a new
MetadataProviderto achieve your goal.