views:

385

answers:

1

My task is to change the ErrorMessage property of the DataAnnotation validation attribute in MVC2.0. For example I should be able to pass an ID instead of the actual error message for the Model property and use that ID to retrieve some content(error message) from a another service e.g database, and display that error message in the View instead of the ID. In order to do this I need to set the DataAnnotation validation attribute’s ErrorMessage property.

    [StringLength(2, ErrorMessage = "EmailContentID.")]
    [DataType(DataType.EmailAddress)]        
    public string Email { get; set; }

It seems like an easy task by just overriding the DataAnnotationsModelValidatorProvider ‘s protected override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable attributes)

However it seems to be a complicated enough.

a. MVC DatannotationsModelValidator’s ErrorMessage property is read only. So I cannot set anything here b. System.ComponentModel.DataAnnotationErrorMessage property(get and set) which is already set in MVC DatannotationsModelValidator so we cannot set again. If you try to set you get “The property cannot set more than once…” error message appears.

public class CustomDataAnnotationProvider : DataAnnotationsModelValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        IEnumerable<ModelValidator> validators = base.GetValidators(metadata, context, attributes);

        foreach (ValidationAttribute validator in validators.OfType<ValidationAttribute>())
        {
            messageId = validator.ErrorMessage;
            validator.ErrorMessage = "Error string from DB And" + messageId ;
        }

        //......
    }
}

Can anyone please help me on this?

+1  A: 

Here is the question: What is your motivation to changing the error message property?

Think this through very carefully, as you are heading down a path where you are obfuscating what is actually happening in the application. Certainly the database informatino is useful, but it is not really part of the validation, nor should it be.

When you head in this direction, you are essentially saying that the validation can only be invalid if there is a database problem. I see two issues with this:

  1. It breaks the separation of concerns. You are reporting a persistance error in the model, which is not where it occurred.
  2. The solution is not unit testable, as you must engage the database.

I don't like either of the two above.

Can you solve this? Possibly if you will create your own custom validation attribute. I would have to check and ensure that is correct. Another option is to aim for custom validation:

http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

This article can also help you head in the direction you desire:

http://ryanrivest.com/blog/archive/2010/01/15/reusable-validation-error-message-resource-strings-for-dataannotations.aspx

Do you want to solve this? Not really if you are attempting to keep a proper separation of concerns in your application. I would not polute my validation error message (this is not valid) with a database error (I am not valid, but the database also blew up). Just my two cents.

Peace and Grace, Greg

Gregory A Beamer