views:

623

answers:

3

The behavior described here appears to now be the default for ASP.NET MVC 2 (at least for Preview 1).

When modelbinding a querystring like this :

 ?Foo=&Bar=cat 

The following binding occurs (assuming you're binding to a model with 'Foo' and 'Bar' string properties)

ASP.NET MVC 1

 model.Foo = "";
 model.Bar = "cat":

ASP.NET MVC 2 (preview 1 through RC)

 model.Foo = null;
 model.Bar = "cat":

Wanted to give anyone who is playing with V2 a heads up since this wasn't mentioned in the 'gu-notes'. Also curious if anyone in the know can comment on whether or not this will be the final implementation or a configurable feature? I'm fine either way but just hope they dont switch back to the old way ! Being configurable would be even better.

Edit: The lesson to learn from this point is whatever version you're developing against not to write code that says Foo.Length == 0 to test for an empty string or Foo.Length > 3 to check for a minimum length. Use string.IsNullOrEmpty(Foo) and/or check for null first.


Update: This question sparked my curiosity as to why they would actually make this change. I think that I stumbled on the answer while researching disabled controls. The W3 HTML spec defines a 'successful control' as follows :

A successful control is "valid" for submission. Every successful control has its control name paired with its current value as part of the submitted form data set. A successful control must be defined within a FORM element and must have a control name.

In other words - a successful control is one that will make it back to the server as a query string parameter. Now, if a control doesn't have a valid value then according to the spec :

If a control doesn't have a current value when the form is submitted, user agents are not required to treat it as a successful control.

(spot the 'open to interpretation' language here with 'not required to...')

So I think by sending a null instead of an empty string it reduces browser incompatibilites where certain browsers may send Foo=&Bar= and others may not even send that query string parameter. By always interpreting Foo= as if Foo wasn't there at all forces you to be more defensive.

I think I'm at least on the right track as to the reason why here - and at least in part has something to do with the notion of a 'succcessful control'.

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

+2  A: 

Null is more representative of what it actually is, and it is compatible with other nullable types besides string, so I imagine it's by design.

Robert Harvey
i could see this being a problem for people that have already built large applications assuming "" and checking Foo.Length == 0. perhaps they had to do it because of some of the new binding functionality. i kinda like having "" sometimes becasue it shows me that something was actually set but thats a minor point
Simon_Weaver
Anyone investing that heavily in ASP.Net MVC already should have considered an upgrade path considering how young the MVC framework is.
womp
string.IsNullOrEmpty(..) should cover your bases anyway.
Runeborg
@runeborg fortunately for me it was a 5 minute fix and minimally invasive
Simon_Weaver
A: 

One way to configure would be to replace the default model binder in V2 (or V1) to get consistent behavior. I prefer the null, myself.

Thomas G. Mayfield
+2  A: 

I prefer the behavior of v1. How will you be able to pass an empty string in v2? Additionally, with the latter you can't tell whether foo is in the query parameters or not.

Thomas Freudenberg
nothing like a nullreferenceexception to tell you that you forgot to send something right! at first i thought that really bugged me, but i'm ok with it thinking further. rarely do you need to pass an empty string (or rather distinguish it from a null) in a web context. if you really have to then perhaps they'll have attributes you can decorate properties with. i think we'll see some cool modelbinding features in V2 and i would expect this to factor into that
Simon_Weaver
@thomas just updated my answer with reference to this which i think explains why http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2
Simon_Weaver