shannon
shannon

Reputation: 8784

Emit DataAnnotations [DisplayName] in MVC PropertyValueRequired format string?

Desired behavior

An undecorated non-nullable value-type property in a model automatically gets a validation message "A value is required" added by DefaultModelBinder. I'd like it to instead display "A value is required for {Property DisplayName}".

I can get this to work exactly like this, for DataAnnotated properties, using a string.format template. I can also change the default literal string to display from DefaultModelBinder in this circumstance. I've added a templated string as a resource: PropertyValueRequired -> "Information is required for {0}", as per:

Asp.Net MVC 2 - Changing the PropertyValueRequired string

Changing the default ModelState error messages in ASP.NET MVC 3

Examples here on StackOverflow indicate it is possible, both for MVC DefaultModelBinder and for DataAnnotations Validator. In both links above, the asker indicates he's doing it for DefaultModelBinder (but can't get other aspects working).


Observed behavior

Unfortunately, it outputs the {0} verbatim from MVC DefaultModelBinder (where I instead want the DisplayName inserted).

Are the posts above misleading? Does MVC3 support a format string for PropertyValueInvalid but not PropertyValueRequired? By convention, should I only be using DataAnnotation, and if I see the DefaultModelBinder message does it mean I haven't handled/decorated sufficiently?

I think, in the following post, Darin Dimitrov may be saying that it isn't possible to use a template. Quote: "override the default required error message ... globally, which would be useless."

ASP.NET MVC - Custom validation message for value types


Why I want to do this (prompted by an answerer asking)

Upvotes: 1

Views: 2419

Answers (2)

shannon
shannon

Reputation: 8784

The answer is MVC3 does not support this. From the MVC source:

PropertyValueInvalid

string displayName = propertyMetadata.GetDisplayName();
string errorMessageTemplate = GetValueInvalidResource(controllerContext);
string errorMessage = String.Format(CultureInfo.CurrentCulture, errorMessageTemplate, modelState.Value.AttemptedValue, displayName);
modelState.Errors.Remove(error);
modelState.Errors.Add(errorMessage);

PropertyValueRequired

bindingContext.ModelState.AddModelError(modelStateKey, GetValueRequiredResource(controllerContext));

I didn't look further, but I suppose it is probably related to lack of model member access in some missing value scenarios.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038890

Works for me. Steps:

  1. In App_GlobalResources/Messages.resx add Required => Information is required for {0}
  2. Decorate your model:

    public class MyViewModel
    {
        [Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(Messages))]
        [DisplayName("Bar")]
        public string Foo { get; set; }
    }
    
  3. In the view leave the corresponding field empty:

    @using (Html.BeginForm())
    {
        @Html.LabelFor(x => x.Foo)
        @Html.EditorFor(x => x.Foo)
        @Html.ValidationMessageFor(x => x.Foo)
        <input type="submit" value="OK" />
    }
    
  4. If you submit the form leaving empty the following messages is displayed: Information is required for Bar

Upvotes: 2

Related Questions