When using Entity Framework with ASP.NET MVC, how to handle mandatory fields

asp.net-mvc asp.net-mvc-3 c# entity-framework validation

Question

Let me begin by providing a step-by-step description of my app.

My Entity Framework-generated model comes first. I have the following entities inside of it:

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

Now, I utilize partial classes and take use of EF's OnChanging hooks to create validation on an object. As an example of thePostComment portion of 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
    }
}

Observe that my class descended fromIDataErrorInfo . By default, MVC checks this for validation failures. If any are discovered, the model is invalidated and the saved errors are used as messages by the validation aids in the view. I'm quite sure this dictionary never even gets filled with a value for that attribute when EF throws an exception. In fact, I'm not even convinced if MVC detects the EF-generated error and invalidates the model before looking for a value.

Here is a screen capture of the issue with the example pseudo-validator included so you can verify that it is operational:

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

The error notice didn't appear, as you can see. The field was, however, appropriately validated as invalid. If I enter a value, it validates successfully. Following my extensive investigation on this topic, this is what I have learned:

The model attribute cannot be null, which prevents you from changing the error message that appears for necessary fields. It is not nullable, hence any attempt to bind a null value to it will result in an exception. As it should, MVC ignores this evidence and declares the model invalid. Every location where this exception occurs generates the message. I'm not sure whether the message is produced by EF or MVC (I'm assuming MVC as it was in charge of first swallowing the exception). I have no idea how to modify this message. As you can see, it consistently states "The value " is invalid," which isn't entirely terrible but isn't particularly user-friendly.

It successfully checks to see whether your name is "fred" when it reaches my name validator since no exception is raised. The value supplied in is acceptable in terms of EF. Not until it reaches myOnAuthorChanging it uses to acknowledge that it is not acceptable. This is the proper action to do and it works well.

If, in my OnChanging events, I throw an exception rather thanIDataErrorInfo dictionary I can produce the identical validation message, but it encloses the inputted value in single quotes instead. 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.");
    }

When "test" is entered as the value for Author, the following notice is displayed: "The value 'test' is invalid." Because the value for the mandatory fields is null, there is nothing to place between the single quotes.

Many folks (such as this man) advise you to just set the attribute in your model to nullable. This is not a workable answer. Here's why it may not be:

Error 3031: Problem in mapping fragments starting at line 313:Non-nullable column PostComments.Body in table PostComments is mapped to a nullable entity property.

Additionally, non-nullable types like int simply cannot be made to be nullable, and changing an int to a nullable int is a messy process that I won't even begin to discuss here.

Bottom line: I don't know how to handle such exceptions from EF myself or, at the very least, modify the message it produces. I'm really confused. I just want to tweak a message for what I believed was a pretty straightforward model validation!

1
7
10/13/2019 10:22:48 PM

Accepted Answer

You have found that MVC is verifying your model based on the type not being nullible. This adds errors to ModelState prior to the execution of your own validation.

I previously encountered this issue and was able to work around it by doing my own validation after looping over Modelstate at the beginning of an action (poor!!).

The message that is thrown may thus be customized even if data annotations are not your primary method of validation by adding [Required to the non nullible type in the friend class, and then providing the message.

This is how it looks:

[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;}
  }
}

Fluent validation (http://fluentvalidation.codeplex.com) for mvc has caught my attention, and they seem to switch off the issue in global. Asax, add the line after application start()

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

I might be off on it, however.

9
4/4/2013 10:55:46 AM

Popular Answer

I'm aware that this isn't precisely what you requested for, but I just completed a project in which I utilized MVC 3 Client Side Validation with Data Annotations and discrete Javascript. It has a lot of words, but it really works. Regex, maximum length, needed, and all the other properties may be put up, and they are all client-side validated. As a result, users may validate forms considerably more quickly.

Here are several helpful links with samples, including here, here, and a lovely MSDN sample, here, which you can download and check out.

Hope it's useful,



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow