Processing required fields in ASP.NET MVC using Entity Framework

Let me start by describing my application in a step-by-step format.

First I have a model generated by the Entity Framework. It has the following objects:

http://www.codetunnel.com/EFEntities.jpg

Now, to implement entity validation, I use partial classes and process the OnChanging hooks that EF provides. Here is an example of a partial PostComment class:

 namespace CodeTunnel.Domain.Models { public partial class PostComment : IDataErrorInfo { private Dictionary<string, string> _errors = new Dictionary<string, string>(); partial void OnAuthorChanging(string value) { //Validating anything but required value works fine. //Like this pseudo-validator. if (value.ToLower() != "fred") _errors.Add("Author", "Sorry, your name must be Fred."); } partial void OnBodyChanging(string value) { //Required value validation does not work, I will tell you why below. if (string.IsNullOrEmpty(value)) _errors.Add("Body", "Body is required."); } #region -= IDataErrorInfo methods =- public string Error { get { return string.Empty; } } public string this[string columnName] { get { if (_errors.ContainsKey(columnName)) return _errors[columnName]; return string.Empty; } } #endregion } } 

Please note that my class is inherited from IDataErrorInfo . MVC checks this for default validation errors. If he finds something, he invalidates the model and uses the saved errors as messages for the helpers in the view. I am pretty sure that when EF throws an exception, this dictionary is not even populated with the value of this property. In fact, I’m not even sure that MVC goes so far that it searches for a value after a model is discovered and invalidated after an EF exception is thrown.

Here is a screenshot of the problem, including an example pseudo-validator so you can see that it works:

http://www.codetunnel.com/ValidationError.jpg

As you can see, the error message did not appear. However, he correctly confirmed the field as invalid. If I add a value there, it will be fine. I have done a lot of research on this, and here is what I know:

The reason you cannot customize the error message displayed for required fields is because the model property is not NULL. Since it cannot be nullable, an attempt to associate a null value with it throws an exception. MVC swallows this exception and invalidates the model as it should. A message is generated wherever this exception occurs. I do not know if an EF or MVC message is generated (I assume that MVC, since it was responsible for swallowing the exception in the first place). I do not know how to configure this message. As you can see, he always says: “The value is“ unacceptable. ”Which, I believe, is not entirely terrible, but actually not very convenient for the user.

It gets into my name validator and checks if your name is "Fred" because the exception is not thrown. As for EF, the transmitted value is OK. Only when it comes to my OnAuthorChanging method OnAuthorChanging it realize that this is not good. This is the correct behavior and works fine.

If I add an exception to my OnChanging events instead of adding it to my IDataErrorInfo dictionary, I can generate the same validation message, only it puts the entered value in single quotes. Example:

  partial void OnAuthorChanging(string value) { if (value.ToLower() != "fred") //_errors.Add("Author", "Sorry, your name must be Fred."); throw new Exception("Sorry, your name must be Fred."); } 

This code shows this message when "test" is entered as the value for the Author: "The value" test "is not valid." With required fields, just the value is zero, so there is nothing to put between single quotes.

Several people ( like this guy ) suggest simply setting the property to nullable in your model. This is NOT an acceptable solution. One of the reasons why this is not so:

Error 3031: the problem in displaying fragments starts from line 313: the non-nullable PostComments.Body column in the PostComments table is mapped to the NULL value of the object property.

In addition, setting nullable simply will not work with non-zero types such as int, and switching int to nullable int is a disgusting mess that I will not even delve into.

The bottom line is that I want to handle these exceptions from EF myself, or at least configure the message that it generates, but I don’t know how. I am completely lost. All I want to do is set up a message that I thought was a very simple model check!

+7
source share
2 answers

MVC checks your model based on the fact that the type is not void, as you have discovered. This adds errors to the ModelState before performing a custom check.

I had this before, and get around it by going through ModelState at the beginning of the action and deleting everything, and then doing my own check (bad !!)

Then, even if you do not use data annotations as the main form of verification, you can configure the message that is called by adding [Required for a non-empty type in the friendship class and specify the message.

Something like that:

 [MetadataType(typeof(YourClassMetadata))] public partial class YourClass { //buddyclass to entity class class YourClassMetadata { [Required(ErrorMessage="Your custom overriding error message")] public int NonNullablePropertyThatIsGivingYouProblems {get;set;} } } 

I started to study carefully ( http://fluentvalidation.codeplex.com ) for mvc, and they seem to have disabled the problem globally. asax, in application_start () by adding a line

 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; 

but I could be wrong.

+8
source

I know that this is not exactly what you requested, but I just finished the project last week when I used MVC 3 Client Side Validation with data annotations and unobtrusive javascript. Its quite a lot, but it works great. You can configure the regex, maxlenght, required, and all other attributes, and it checks all this on the client. This greatly simplifies form validation for the user.

here are some useful links with examples here , here and a very good MSDN sample for download and testing here

hope this helps

0
source

All Articles