0

I have an Entity Framework 4.1 model that supports multiple ASP.NET MVC web applications. I use DataAnnotations to define and localize label text and validation rules and error messages.

For some applications, I need the label text for certain fields to differ from the standard, model-defined text. This is easy to achieve for the labels themselves: I retrieve the text I need from a local resource file, associated with the view. However, the label text is also used in validation error messages such as "{fieldname} must have a maximum length of 50 characters".

What is the best way to alter the validation messages without changing the Annotations on the model classes?

Paul Taylor
  • 5,651
  • 5
  • 44
  • 68

2 Answers2

2

Try to redefine error messages in controller for specific cases, like this:

Model:

public class Company
    {
        [Required(ErrorMessage = "The field is required")]
        public string CompanyName { get; set; }
        public string Address { get; set; }
    }

controller:

 [HttpPost]
        public ActionResult Index(Company company)
        {
            if(ModelState.IsValid)
            {
                //your code
            }

            // your custom validation message here
            if (ModelState["CompanyName"].Errors.Any())
                ModelState["CompanyName"].Errors[0] = new ModelError("custom error message");

            return View();
        }
testCoder
  • 7,155
  • 13
  • 56
  • 75
  • That's helpful too, thanks. The only drawback I see is that it puts validation code in specific controller methods, making it hard to reuse across multiple related view. – Paul Taylor Nov 09 '12 at 09:25
1

You have coupled your validation to your entity models. The way to avoid this is to create view models from your entities and put the validation on to those.

Example: If you have the Entity...

public class Product
{
    public string Name {get; set;}
}

you could create two different view models:

public class ProductPageViewModel1
{
    [Required]
    public string Name {get; set;}
}

public class ProductPageViewModel2
{
    [DisplayName("Foo")]
    public string Name {get; set;}

}

Map the entity to the view model and use these in your views.

jeffmaher
  • 1,824
  • 3
  • 21
  • 20
Dan
  • 3,229
  • 2
  • 21
  • 34
  • That would certainly do it, but it means writing view models for each view, and mapping methods to populate the view models from the entity models. From that point of view, it seems an expensive solution. I was hoping to find an easier approach, perhaps an HtmlHelper that manipulates the model metadata to alter the validation messages. – Paul Taylor Nov 08 '12 at 17:33
  • Perhaps expensive short term, but if you plan on scaling your application at all I think it's a good investment. And it will be much more readable in the future than some magic reflection code :). You can use something like Automapper to ease the mapping. Here's a good post that explains the other advantages of using view models: http://stackoverflow.com/a/4878956 – Dan Nov 08 '12 at 17:54
  • Hmm. You've got me thinking, I can see the benefits. Will check out Automapper. – Paul Taylor Nov 09 '12 at 06:31
  • 1
    Automapper is impressive, takes a lot of the work out of this approach. The benefits of decoupling the UI and domain model in this case are compelling so have decided to go this way. – Paul Taylor Nov 12 '12 at 11:34
  • I think you are missing a closing paren ')' on this line `[DisplayName("Foo"]` – TechplexEngineer Aug 07 '13 at 12:42