我不知道为什么我现在才第一次注意到这种行为。希望确认这是否是设计行为,或者我是否遗漏了什么。
假设我有一个实现IEnumerable<T>
并提供附加属性的视图模型。例如:
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
});
在我重构以使视图模型不实现之前IEnumerable<T>
,我想确认这是设计使然,并且应该是可以预期的。我想这是有道理的,因为必须扩展 javascript 数组对象的原型以容纳其他属性。
更新:
我对视图模型进行了以下更改,以避免命名内部 enumerable 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
:
[{"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
在控制器操作返回和调用 jquerysuccess
函数之间,似乎仍然丢失了附加属性。