开发者

How to change ErrorMessage property of the DataAnnotation validation in MVC2.0

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 complica开发者_开发知识库ted 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?


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.


There are built in ways to get the error message via a resource. Instead of a database lookup to get a resource at runtime, generate resources from your database and use that for your error messages.

You can then use the ErrorMessageResourceName and ErrorMessageResourceType to allow the DataAnnotation to perform a resource lookup instead of hard-coding a specific string.

public sealed class MyModel
{
    [Required(
        ErrorMessageResourceName="MyDescriptionResource",
        ErrorMessageResourceType=typeof(MyCustomResource))]
    public string Description { get; set; }
}


Also you may want to have a look at ValidationAttribute.FormatErrorMessage Method on msdn.

This method formats an error message by using the ErrorMessageString property. This method appends the name of the data field that triggered the error to the formatted error message. You can customize how the error message is formatted by creating a derived class that overrides this method.

A quick sample (and not meant to be a definitive example)

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, 
                Inherited = true)]
public sealed class PostCodeValidationAttribute
    : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        if( value == null )
            return true;

        string postCode = value as string;
        if( string.IsNullOrEmpty(postCode) )
            return true;

        if ( !PostCode.IsValidPostCode(postCode, this.PostCodeStyle) )
            return false;

        return true;
    }

    public PostCodeStyle PostCodeStyle { get; set; } 

    public override string FormatErrorMessage(string name)
    {
        return string.Format(
            "{0} is not a valid postcode for {1}", name, PostCodeStyle);
    }
}

* I've omitted the PostCodeStyle enumeration as well as the PostCode class for validating a postcode.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜