Tagged: metadatatype Toggle Comment Threads | Keyboard Shortcuts

  • danielsaidi 11:37 am on July 5, 2010 Permalink | Reply
    Tags: , constraintexception, , , metadatatype,   

    ConstraintException thrown when posting empty data for non-nullable properties 

    I am currently working with model validation, using an EF4 entity model, DataAnnotations and partial classes with MetadataType connections.

    In my model, I have an Employee entity for which some of properties are non-nullable. I have also created a partial class and a meta data class for model validation, as is described in this blog post.

    This works great. The Employee class is validated properly, with minimum effort. My entities are validated with standard validation attributes as well as custom ones. Lovely.

    However, the application crashes when I post empty text input elements in my Create/Edit views. A ConstraintException is thrown before my view controller actions are executed, which means that I cannot act on the constraint exception within my action.

    The exception is caused by the fact that empty posted data will cause the corresponding model properties to be set to null, which conflicts with the non-nullable properties in the entity model.

    However, since I have custom model validation classes in which I add Required attributes to mandatory properties, I do not need the non-nullable attributes in my entity model. As such, I set the nullable property to (None)…and the ConstraintException is history!

     
    • Thomas 3:29 pm on September 24, 2010 Permalink | Reply

      Surely this is the incorrect approach, as it means you have no constraints set at the root database level. Which seems wrong.

      There is actually no problem with a constraint exception being thrown, that’s exactly what is supposed to happen.

      • danielsaidi 11:57 am on October 4, 2010 Permalink | Reply

        Hi Thomas! Thank you for your input, you are absolutely right. I have updated the post according to your feedback.

    • temStetLody 10:05 pm on June 21, 2011 Permalink | Reply

      Hello all! I like this forum, i found numberless interesting people on this forum.!!!

      Large Community, good all!

    • Hector 4:47 pm on June 3, 2012 Permalink | Reply

      I know, I know, it has been almost two years since this was posted.
      But just in case someone else is looking here for a solution, I just managed to get around.
      You may use the “DisplayFormat” DataAnnotation in order to override the default behavior (empty posted data causes corresponding model properties set to null), like this:

      [DisplayFormat(ConvertEmptyStringToNull = false)]

      Add the annotation for each non-nulleable attribute of the model. Then, EntityException is gone, and validation still works.

      Best regards.

      • danielsaidi 4:53 pm on June 3, 2012 Permalink | Reply

        Yeah, the post is rather old…and invalid. I should update it, but…well 😉

        Thank you so much for your comment!

  • danielsaidi 1:03 am on July 5, 2010 Permalink | Reply
    Tags: callwithmodelvalidation, , , metadatatype, modelstate, ,   

    DataAnnotations and MetadataType fails in unit tests 

    This post describes how to solve the problem that model validation will not work for ASP.NET MVC2 (.NET 4.0) when testing a model that uses DataAnnotations and MetadataType to describe for its validation.

    First of all, ModelState.IsValid is always true, since the functionality that sets it to false if the model is invalid is never executed during the test cycle. This will cause your controllers to behave incorrectly during your tests.

    Second, MetadataType binding is ignored during the test cycle as well. This will cause the validation within it to be ignored as well, which in turn will cause the model to be valid although an object is invalid.

    My situation

    I am currently writing tests for a Create method in one of my controllers. I use NUnit as test framework. I have an EF4 Entity Model, in which I have a couple of entities. For instance, I have an Employee entity with FirstName, LastName and Ssn properties.

    To enable model validation, I create a partial Employee class in the same namespace as the EF4 entity model, then create a MetadataType class, which handles validation for the class. This approach is fully described in this blog post.

    In my EmployeeController, I have a Create method that takes an employee and tries to save it. If ModelState.IsValid is false, the controller returns the Create view again and displays the errors. If the model is valid, however, I create the employee and return the employee list.

    Easy enough. Well, when I started to write tests, I realized that ModelState.IsValid is always true, even if I provide the method with an invalid employee. Turns out that model validation is not triggered by the unit test.

    Trigger model validation within a test

    This blog post describes the ModelState.IsValid problem and provides a slick solution – the CallWithModelValidation Controller extension method.

    I added this extension method to my MVC2 project and used it instead of calling Create, as such:

       Before:
       var result = controller.Create(new Employee());
    
       After:
       var result = controller.CallWithModelValidation(c => c.Create(new Employee()), new Employee());

    And sure enough, this causes the test to trigger model validation. The only problem is that the model validation does not catch any errors within the model, even if the model is invalid.

    After some fiddling, I noticed that this error only occurs for partial objects that uses MetadataType to specify model validation. A class that describes its validation attributes directly is validated correctly.

    Turns out that the MetadataType class is ignored within test context. Thus, the model is always considered to be valid.

    Register MetadataType connections before testing

    This blog post describes the MetadataType problem and provides a slick solution – the InstallForThisAssembly method.

    This method must be placed within the same assembly as the model, in other words not the test project. I placed it in a ControllerExtensions class file and call it at the beginning of CallWithModelValidation. This works, but will not work if you move the extension to another project.

    Run it before your tests, and everything will work “as it should”.

    Hope this helps.

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel