2

I have the following:

This action:

public virtual ActionResult Search(string search, string sort)
{
...
}

Called from this url with empty query string parameters:

http://myurl.com/mycontroller/search?search=&sort=

Now my understanding was that as of MVC 2 the DefaultModelBinder would leave these values as nulls. However, what I am finding is that they are actually set to empty strings. Is this in fact the expected behavior? Is this documented anywhere?

Thanks

1
  • Did you override the default model binder is some way? did you add a custom model binder? Commented Jun 13, 2012 at 21:50

3 Answers 3

6

Yes, The defualt behavior is setting empty strings to null, but it can be overriden with changing ConvertEmptyStringToNull = false;

true if empty strings that are posted back in forms should be converted to null;
otherwise, false. The default value is true.

msdn

like in this code:

public class SimpleArrayModelBinder : DefaultModelBinder 
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    {
        if (bindingContext.ModelType == typeof(string)) 
        {
            var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            bindingContext.ModelMetadata.ConvertEmptyStringToNull = false;
            if (value == null || value.AttemptedValue.IsNullOrEmpty())
                return "";
            else
                return value.AttemptedValue;
        }
    }
}

One more way to change the deafult behavior is with the ConvertEmptyStringToNull attribute above the properties in your model.

Example:

public class Person
{
    [DisplayFormat(ConvertEmptyStringToNull = false)]
    public string Lastname { get; set; }
    ...
}

Blog

Sign up to request clarification or add additional context in comments.

6 Comments

OK I think this is where I'm getting lost. The documentation here msdn.microsoft.com/en-us/library/… says that these empty strings are converted to null. What am I missing?
I've read this sevarl times but maybe I'm just misinterpreting it. It says "true if empty strings that are posted back in forms should be converted to null;" I read that as passing true (which is the default) will convert empty strings to null, not the other way around.
I'm seeing that this doesn't apply when your action expects a simple type.
@tribus. What do you mwan by "this doesn't apply"?
The default behavior of setting empty strings to null seems to only apply when the model is a complex type. For simple types the ModelMetadata.ConvertEmptyStringToNull property is never checked.
|
1

After looking through the source code for the DefaultModelBinder what I have found is that the ModelMetadata.ConvertEmptyStringToNull property is only ever checked when the model being bound is a complex model. For primative types exposed in an action, the values are retrieved as is. For the example in my original question, this would be an empty string.

From the DefaultModelBinder source

        // Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string))
        // or by seeing if a value in the request exactly matches the name of the model we're binding.
        // Complex type = everything else.
        if (!performedFallback) {
            bool performRequestValidation = ShouldPerformRequestValidation(controllerContext, bindingContext);
            ValueProviderResult vpResult = bindingContext.UnvalidatedValueProvider.GetValue(bindingContext.ModelName, skipValidation: !performRequestValidation);
            if (vpResult != null) {
                return BindSimpleModel(controllerContext, bindingContext, vpResult);
            }
        }
        if (!bindingContext.ModelMetadata.IsComplexType) {
            return null;
        }

        return BindComplexModel(controllerContext, bindingContext);
    }

So as far as I can tell ModelMetadata.ConvertEmptyStringToNull only applies when bindng a complex type.

Comments

0

ModelMetadata.ConvertEmptyStringToNull this property will affect when binding the values to strings that sits as properties inside a Model.

Ex.

public class Employee
{
   public string First{get;set;}
   public string Last{get;set;}
}

With ModelMetadata.ConvertEmptyStringToNull = true (that is default)

You will see both First and Last as null when the request doesn't contains values for these items.

With ModelMetadata.ConvertEmptyStringToNull = false

The properties will be "" when the request contains those parameters with empty values. If the request doesn't contain the parameter itself then still the value will be null.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.