我不知道为什么我现在才第一次注意到这种行为。希望确认这是否是设计行为,或者我是否遗漏了某些东西。
假设我有一个实现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
函数之间,似乎仍然丢失了附加属性。
答案 0 :(得分:3)
对于实现IEnumerable的类,JavascriptSerializer
仅序列化枚举项。它调用GetEnumerator()
来获取要序列化的数据,忽略任何其他属性。这就是为什么Count
的{{1}}属性没有被序列化,也没有任何其他属性。
原因是这种类型的构造不能用json格式表示。要包含序列化程序必须创建散列对象而不是数组的其他属性,但严格来说,散列对象不是集合。 (例外情况是像List<T>
这样的键/值对类,它们被序列化为哈希对象。但规则代表 - 只有枚举的字典条目被序列化。)
但是为什么要创建一个直接实现Dictionary
的类来序列化为json而不是这样做呢?
IEnumerable