Error messages for model validation using data annotations
Given the following classes:
using System.ComponentModel.DataAnnotations;
public class Book{
public Contact PrimaryContact{get; set;}
public Contact SecondaryContact{get; set;}
[Required(ErrorMessage="Book name is required")]
public string Name{get; set;}
}
public class Contact{
[Required(ErrorMessage="Name is required")]
public string Name{get; set;}
}
Is there a clean way I can give a distinct error message for each ins开发者_如何学运维tance of Contact
in Book
using DataAnnotations
? For example, if the name was missing from the PrimaryContact
instance the error would read "primary contact name is required".
My current solution is to create a validation service that checks the model state for field errors, then remove said errors and add them back using the specific language I'd like.
This is the only way I know of that, but it's far from clean. It involves using subclassing and MetaData classes to "override" the error message.
public class Book
{
public PrimaryContact PrimaryContact { get; set; }
public SecondaryContact SecondaryContact { get; set; }
[Required(ErrorMessage = "Book name is required")]
public string Name { get; set; }
}
public class Contact
{
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
}
[MetadataType(typeof(PrimaryContactMD))]
public class PrimaryContact : Contact
{
class PrimaryContactMD
{
[Required(ErrorMessage = "Primary Contact Name is required")]
public string Name { get; set; }
}
}
[MetadataType(typeof(SecondaryContactMD))]
public class SecondaryContact : Contact
{
class SecondaryContactMD
{
[Required(ErrorMessage = "Secondary Contact Name is required")]
public string Name { get; set; }
}
}
You may want to look at using the CustomValidation
attribute for such properties instead of relying on the Required
attribute.
CustomValidation
will allow you to more granularly tailor your validation messages to the property you are validating. I've used context.DisplayName
to dynamically display the name of the property being validated just for brevity, but this can be customized further based on your needs.
If even further customization is needed, you can write different CustomValidation
handlers for each individual property instead of just reusing the same one as I've done in my code example.
using System.ComponentModel.DataAnnotations;
public class Book {
[CustomValidation(typeof(Book), "ValidateContact")]
public Contact PrimaryContact { get; set; }
[CustomValidation(typeof(Book), "ValidateContact")]
public Contact SecondaryContact { get; set; }
[Required(ErrorMessage = "Book name is required")]
public string Name { get; set; }
public static ValidationResult ValidateContact(Contact contact, ValidationContext context) {
ValidationResult result = null;
if (contact == null) {
result = new ValidationResult($"{context.DisplayName} is required.");
} else if (string.IsNullOrWhiteSpace(contact.Name)) {
result = new ValidationResult($"{context.DisplayName} name is required.");
}
return result;
}
}
public class Contact {
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
}
The Below code in c# to format data annotations error and format in append format in single string
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ModelState.IsValid == false)
{
if (actionContext.ModelState.IsValid) return;
string errors = actionContext.ModelState.SelectMany(state => state.Value.Errors).Aggregate("", (current, error) => current + (error.ErrorMessage + ". "));
}
}
}
I'm looking for answer to this too, what I have found so far if you do something like: "{0} Contact Name is required" in the Error message it will automatically substitute the name of the variable. I figure there is a way to explicitly use this feature.
精彩评论