locked
DataAnnotationsModelBinder throws NullReferenceException RRS feed

  • Question

  • User-1912369449 posted

    DataAnnotationsModelBinder works fine with ViewModels which are not made up of complex object hierarchies, such as 


    public class Baz<o:p></o:p>

            {<o:p></o:p>

                [Required]<o:p></o:p>

                public string Bar { get; set; }<o:p></o:p>

            }

     

    However, DataAnnotationsModelBinder does not work with complex ViewModels such as this one:<o:p></o:p>

    public class Foo
        {
            public Baz MyBaz { get; set;}
           
            #region Nested type: Baz

            public class Baz
            {
                [Required]
                public string Bar { get; set; }
            }

            #endregion
        }

     

     If my view posts a value for Foo.Baz.Bar,  the DataAnnotationsModelBinder  throws a NullReferenceException when trying to bind the model. This is a big problem for me since I really prefer using custom ViewModels instead of untyped ViewData arrays, so I often end up putting Linq entites inside a wrapper class to create a custom ViewModel. <o:p></o:p>

    The only workaround I have found so far is to expose the properties you need to post back from the view in the topmost hierarchy layer of the ViewModel:<o:p></o:p>

    public class Baz<o:p></o:p>

            {<o:p></o:p>

                [Required]<o:p></o:p>

                public string Bar { get; set; }<o:p></o:p>

            }<o:p></o:p>

    <o:p> </o:p>

    public class ViewModel<o:p></o:p>

            {<o:p></o:p>

                private Baz myBazInstance;<o:p></o:p>

                <o:p></o:p>

                [Required]<o:p></o:p>

                public string ExposedBar<o:p></o:p>

                {<o:p></o:p>

                    get { return MyBaz.Bar; }<o:p></o:p>

                    set { MyBaz.Bar = value; }<o:p></o:p>

                }<o:p></o:p>

    <o:p> </o:p>

                public Baz MyBaz<o:p></o:p>

                {<o:p></o:p>

                    get { return myBazInstance ?? (myBazInstance = new Baz());}<o:p></o:p>

                    set { myBazInstance = value; }<o:p></o:p>

                }<o:p></o:p>

            }<o:p></o:p>

    But I don’t want to write this extra code for every single property in my linq entity.  Also, I really don’t want to repeatedly the ValidationAttributes I already typed in my Linq Entity as I did above. Has anyone else seen this problem and is there a better workaround?

    Monday, May 4, 2009 1:13 PM

Answers

  • User-1032240251 posted

    The fix for this issue is simple, as others have noted.

    In the BindProperty method, you will find this line of code:

        if (modelState.Errors.Count == 0) {

    It should be changed to:

        if (modelState == null || modelState.Errors.Count == 0) {

    We are intending to include DataAnnotations support in MVC 2, which will include the DataAnnotationsModelBinder. This feature will be part of the first CTP.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, June 13, 2009 10:12 PM

All replies

  • User-1032240251 posted

    I'll take a look at this soon and let you know.

    - Brad

    Monday, May 4, 2009 2:03 PM
  • User-1912369449 posted

     Thanks, Brad! I really appreciate this. [:)]

    Tuesday, May 5, 2009 4:58 AM
  • User-1912369449 posted

     Sorry to urge you Brad, but have you had the time to have a look?

     Thanks,

     Adrian

    Monday, May 11, 2009 3:51 AM
  • User889692731 posted

     I've spotted the same issue and left a comment on Brad's blog.

    This is a great modelbinder, should have been built within MVC to start with in my humble opinion.

    Hope you can solve it soon.

    Monday, May 11, 2009 4:12 AM
  • User-1032240251 posted

    The fix for this issue is simple, as others have noted.

    In the BindProperty method, you will find this line of code:

        if (modelState.Errors.Count == 0) {

    It should be changed to:

        if (modelState == null || modelState.Errors.Count == 0) {

    We are intending to include DataAnnotations support in MVC 2, which will include the DataAnnotationsModelBinder. This feature will be part of the first CTP.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, June 13, 2009 10:12 PM
  • User889692731 posted

    Thanks.

     When will the CTP be out?

    Sunday, June 14, 2009 4:38 AM