Note that there are some explanatory texts on larger screens.

plurals
  1. POInconsistent behavior in HtmlHelper methods retrieving model metadata
    text
    copied!<p>I’m tracing down an unexpected behavior in MVC3, having to do with how it gets model metadata.</p> <p>I had previously talked to one of my developers about using the same EditorTemplate for some data which is collected in two different areas of the system. The data fields are almost identical, except for the [Required] attribute. In one page certain fields are required, in the other page they are not. Theoretically this can be accomplished by using a base model which has the common attributes on each field, and inheriting those models, overriding the properties and adding additional validation attributes. For example:</p> <pre><code>class BaseModel { [Display(Name=”My Label”)] public virtual string MyLabel { get; set ;} } class RequiredModel : BaseModel { [Required] public override string MyLabel { get; set ;} } </code></pre> <p>Then the View can be strongly typed to BaseModel, and calls to @Html.EditorFor(m=>m.MyLabel) in the view should pick up the correct attributes, depending on whether the actual instance of the model is a BaseModel or RequiredModel.</p> <p>That’s the theory.</p> <p>And in fact, it works well if you use the “old” HTML helper, e.g. @Html.TextBox(“MyLabel”). Those call ModelMetadata.FromStringExpression(field), which correctly gets the metadata from RequiredModel if the concrete model instance is RequiredModel. The newer helper methods call ModelMetadata.FromLambdaExpression(expression), which does NOT correctly get the metadata from the correct concrete instance.</p> <p>Is this a bug in MVC? Intentional behavior? Is there a workaround, or a better way to address this problem?</p> <p>This is of course a trivial example, the actual code we're dealing with has about 20 fields with some complex business rules and interaction, which is the same on both pages EXCEPT for which fields are required.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload