0

For a very long time, I thought applying the ReadOnly attribute to a viewmodel property meant that the generated element would have the readonly HTML attribute.

Then I was very dissapintd to discover that this ReadOnly attribute only applied to model binding, and that the value in a read-only input isn't bound to the posted viewmodel, and people could still type in the UI field, letting them think the value would be stored.

Now I have to go through my viewmodel, and wherever there is this attribute, comment it out, and manually apply the HTML readonly attributes to the Razor elements affected.

I would now like to make a ReallyReadOnly attribute, so that for viewmodel properties marked as such, a genuine read-only input is generated, and its value is bound back to the posted view model

Where can I, if I can, in the rendering process, can I check for and act on this new attribute?

ProfK
  • 49,207
  • 121
  • 399
  • 775
  • 2
    Not an easy task. You would need to create your own `HtmlHelper` extension method that reads the property metadata (the `.IsReadOnly` value) and adds the `readonly="readonly"` attribute to the html that it outputs. –  May 26 '16 at 04:34
  • 3
    It's not misleading. There are literally hundreds of attributes, most of which do not apply to models, and would simply be ignored. You are responsible for understanding which attributes apply and which don't. Attributes can be used for many purposes, so there's no way the system could warn you of this. – Erik Funkenbusch May 26 '16 at 04:45
  • @StephenMuecke That is what I have in mind. A new helper extension called e.g. `ReadOnlyInput` that reads model metadata and checks for that new attribute. Since there seem to be very few other options, why not make your comment an answer? – ProfK May 26 '16 at 18:04
  • 1
    @ProfK, Not the same but [this answer](http://stackoverflow.com/questions/26482305/access-model-class-instance-from-a-custom-additionalmetadataattribute-asp-net-m/26483022#26483022) gives an example of creating a helper that added the attributes (and you could create overloads that adds `readonly` is `htmlAttributes` are supplied). In that case, its based on providing a `bool` parameter, but that can be removed and the method can be just `@Html.ReadOnlyTextBoxFor(m => m.YourProperty)`. But because the extension method is specific, there is no real need to use the attribute. –  May 27 '16 at 05:01
  • An alternative would be to create a `@Html.MyTextBoxFor()` method, which does read the `ModelMetadata.IsReadonly` property and adds the attribute as required, but that would mean replacing all your current `@Html.TextBoxFor()` methods in your views –  May 27 '16 at 05:03

1 Answers1

0

Sadly, the absolute simplest solution I know of for this is to use a ReadOnly editor template that you apply to your model, similar to the description given here for dates.

You will have duplication if you also want to apply the ReadOnly for model binding, but at least its in the exact same spot.

Community
  • 1
  • 1
xianwill
  • 523
  • 3
  • 9