MVC 3空查询字符串参数值绑定为空字符串而不是null

时间:2012-06-13 20:52:50

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-2 defaultmodelbinder

我有以下内容:

此操作:

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

使用空查询字符串参数从此网址调用:

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

现在我的理解是,从MVC 2开始,DefaultModelBinder会将这些值保留为空值。但是,我发现它们实际上是设置为空字符串。这实际上是预期的行为吗?这是在任何地方记录的吗?

由于

3 个答案:

答案 0 :(得分:6)

是的,defualt行为是将空字符串设置为null,但可以通过更改ConvertEmptyStringToNull = false;来覆盖它

  

true 如果在表单中回发的空字符串应转换为null ;

  否则,错误。 默认值为true

msdn

就像在这段代码中一样:

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;
        }
    }
}

更改deafult行为的另一种方法是使用模型中属性上方的ConvertEmptyStringToNull属性。

示例:

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

Blog

答案 1 :(得分:1)

在查看DefaultModelBinder的源代码之后,我发现只有在绑定的模型是复杂模型时才会检查ModelMetadata.ConvertEmptyStringToNull属性。对于在动作中公开的主要类型,将按原样检索值。对于我原始问题中的示例,这将是一个空字符串。

来自DefaultModelBinder源

        // 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);
    }

据我所知,ModelMetadata.ConvertEmptyStringToNull仅在绑定复杂类型时适用。

答案 2 :(得分:0)

ModelMetadata.ConvertEmptyStringToNull此属性会在将值绑定到作为Model内的属性的字符串时生效。

实施例。

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

使用ModelMetadata.ConvertEmptyStringToNull = true(默认值)

当请求不包含这些项的值时,您会将FirstLast都视为null

使用ModelMetadata.ConvertEmptyStringToNull = false

当请求包含具有空值的参数时,属性将为“”。如果请求不包含参数本身,则值仍为null