Modelbinding for empty query string parameters in ASP.NET MVC 2
Asked Answered
G

3

17

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

Gonsalves answered 11/8, 2009 at 23:40 Comment(2)
Thanks ... this one give me little headache to find ... I wonder why this change was made though ... It doesn't really add any value except more work for us ! Is it related to memory optimization ?? does an empty string take some memory in the face of a null ???Aircraftman
@jalchr - i've updated my question with what i think is the reason why they did thisGonsalves
M
4

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.

Monody answered 12/8, 2009 at 2:9 Comment(4)
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 pointGonsalves
Anyone investing that heavily in ASP.Net MVC already should have considered an upgrade path considering how young the MVC framework is.Clinch
string.IsNullOrEmpty(..) should cover your bases anyway.Anesthesiology
@runeborg fortunately for me it was a 5 minute fix and minimally invasiveGonsalves
F
4

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.

Franks answered 13/8, 2009 at 12:2 Comment(2)
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 thatGonsalves
@thomas just updated my answer with reference to this which i think explains why w3.org/TR/html401/interact/forms.html#h-17.13.2Gonsalves
L
0

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.

Laureen answered 12/8, 2009 at 18:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.