MVC不是json序列化实现IEnumerable <t>的模型上的其他属性吗?</t>

时间:2012-08-10 16:03:50

标签: asp.net-mvc arrays json asp.net-mvc-3 ienumerable

我不知道为什么我现在才第一次注意到这种行为。希望确认这是否是设计行为,或者我是否遗漏了某些东西。

假设我有一个实现IEnumerable<T>的viewmodel,并提供其他属性。例如:

public class MyResultsViewModel : IEnumerable<MyResultViewModel>
{
    public IEnumerable<MyResultViewModel> Results { get; set; }
    public string SomeAdditionalProperty { get; set; }

    public IEnumerator<MyResultViewModel> GetEnumerator()
    {
        return Results.GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator; }
}

假设我还有一个控制器,它将此模型作为json返回。例如:

public ActionResult MyResults()
{
    var entities = PrivateMethodToGetEntities();
    var models = Mapper.Map<MyResultsViewModel>(entities);
    models.SomeAdditionalProperty = "I want this in the JSON too";
    return Json(models, JsonRequestBehavior.AllowGet);
    // models now contains a populated Results as well as the add'l string prop
}

当我从客户端的JSON请求中获得结果时,它总是以数组的形式返回。例如:

$.get('/Path/To/MyResults')
.success(function (results) {
    alert(results.SomeAdditionalProperty); // this alerts 'undefined'
    alert(results.length); // this alerts the size / count of Results
    alert(results[0]); // this alerts object
    // inspecting results here shows that it is a pure array, with no add'l props
});

在我重构以使viewmodel不实现IEnumerable<T>之前,我希望得到一些确认,这是设计的,应该是预期的。我想这是有道理的,因为必须扩展javascript数组对象的原型以适应其他属性。

更新

我对viewmodel进行了以下更改,以避免命名内部可枚举Results

public class MyResultsViewModel : IEnumerable<MyResultViewModel>
{
    public IEnumerable<MyResultViewModel> NotNamedResults { get; set; }
    public string SomeAdditionalProperty { get; set; }

    public IEnumerator<MyResultViewModel> GetEnumerator()
    {
        return NotNamedResults.GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator; }
}

通过此更改,行为仍然存在。 alert(JSON.stringify(results))为我的枚举MyResultViewModel s集合

生成正常的数组语法
  

[{ “ResultProp1”: “A”, “ResultProp2”: “AA”, “ResultProp3”: “AAA”},{ “ResultProp1”: “B”, “ResultProp2”: “BB”, “ResultProp3” : “BBB”},{ “ResultProp1”: “C”, “ResultProp2”: “CC”, “ResultProp3”: “CCC”},{ “ResultProp1”: “d”, “ResultProp2”: “DD”,” ResultProp3 “:” DDD “},{” ResultProp1 “:” E”, “ResultProp2”: “EE”, “ResultProp3”: “EEE”}]

在控制器操作返回JsonResult并调用jquery success函数之间,似乎仍然丢失了附加属性。

1 个答案:

答案 0 :(得分:3)

对于实现IEnumerable的类,JavascriptSerializer仅序列化枚举项。它调用GetEnumerator()来获取要序列化的数据,忽略任何其他属性。这就是为什么Count的{​​{1}}属性没有被序列化,也没有任何其他属性。

原因是这种类型的构造不能用json格式表示。要包含序列化程序必须创建散列对象而不是数组的其他属性,但严格来说,散列对象不是集合。 (例外情况是像List<T>这样的键/值对类,它们被序列化为哈希对象。但规则代表 - 只有枚举的字典条目被序列化。)

但是为什么要创建一个直接实现Dictionary的类来序列化为json而不是这样做呢?

IEnumerable