Json空数组在MVC中反序列化为null

Ian*_*ill 23 c# json json.net asp.net-mvc-3

我有一个控制器动作,它接收一个整数和一个对象,包含各种属性,其中一个是对象的通用列表.当我使用填充列表将JSON发布到操作时,一切都正确映射,我得到一个包含我发布的对象的列表.但是,如果数组为空,则MVC操作会将该属性绑定到空列表的null intead.我希望空数组映射到空数组而不是空数,因为在这种情况下空数组意味着集合中没有任何内容,而null意味着应该检查数据库以查看以前是否有任何内容保存在集合中,但我无法弄清楚我需要更改以使其正确映射.我们使用Json.Net为返回对象进行对象序列化,但我认为它不会用于模型绑定上的对象反序列化.

传递的对象:

public class ObjectInList
{
    public decimal Value1 { get; set; }
    public decimal Value2 { get; set; }
}

public class Criteria
{
    public decimal? ANullableNumber { get; set; }
    public IList<ObjectInList> ObjectsList { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Json请求:"{\"id \":137,\"criteria \":{\"ObjectsList \":[]}}"

控制器动作:

public ActionResult ProcessCriteria(int id, Criteria criteria)
{
    return Json(_service.ProcessCriteria(id, criteria));
}
Run Code Online (Sandbox Code Playgroud)

我在控制器操作中获取null而不是条件对象中的空列表.无论我是否为其他属性发送空值,都会发生这种情况.不确定它是否属于IList而不是IEnumerable?(包装服务调用的Json方法是我们的​​包装器,它使用Json.Net返回一个json结果来序列化响应 - null是在收到的条件对象中,而不是在返回中.)

我猜这是一件非常简单的事情,我很想念,但我无法解决什么问题,任何帮助都非常感激.

yga*_*don 11

好吧,我正在面对这个问题差不多5个小时尝试找到解决方案然后我发现自己在寻找MVC源代码.我发现这是 第173行的System.Web.Mvc.ValueProviderResult中的Mvc源代码的问题:

        else if (valueAsArray != null)
        {
            // case 3: destination type is single element but source is array, so                     extract first element + convert
            if (valueAsArray.Length > 0)
            {
                value = valueAsArray.GetValue(0);
                return ConvertSimpleType(culture, value, destinationType);
            }
            else
            {
                // case 3(a): source is empty array, so can't perform conversion
                return null;
            }
        }
Run Code Online (Sandbox Code Playgroud)

正如你可以看到source是否为空数组,它将返回null.

所以我必须找到解决方法,然后我记得在过去的好时光中我们正在进行反序列化:这就是你将如何得到你想要的东西:

    public ActionResult ProcessCriteria(int id, Criteria criteria)
    {
        var ser = new System.Web.Script.Serialization.JavaScriptSerializer();
        StreamReader reader = new StreamReader(System.Web.HttpContext.Current.Request.InputStream);
        reader.BaseStream.Position = 0;
        criteria = ser.Deserialize<Criteria>(reader.ReadToEnd());

        return Json(_service.ProcessCriteria(id, criteria));
    }
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是一个明显的错误。您可以在那里发布问题或进行提交 http://aspnetwebstack.codeplex.com/ (2认同)

mar*_*rto 0

这是我发表的评论:

public class Criteria
{
    public decimal? ANullableNumber { get; set; }
    private IList<ObjectInList> _objectsList = new List<ObjectInList>();
    public IList<ObjectInList> ObjectsList 
    { 
        get { return _objectsList; } 
        set { 
            if(value != null) 
                _objectsList = value;
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

  • 正如我在上面的评论中所说,我希望这个列表也能够有一个空状态,所以如果我在这种情况下尝试发送一个空值,它仍然会显示为一个空列表 - 这不是所需的行为。 (2认同)