Answered by:
DataAnnotationsModelBinder throws NullReferenceException

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