我有一个模型如下:
public class TestResultModel { public bool Successful { get; set; } public string ErrorMessage { get; set; } } public class TestResultListModel : List<TestResultModel> { public int TotalTestCases { get { return base.Count; } } public int TotalSuccessful { get { return base.FindAll(t => t.Successful).Count; } } }
我TestResultListModel从返回ApiController:
TestResultListModel
ApiController
var testResultListModel = new TestResultListModel(); foreach (var testCaseId in new int[] {1,2,3,4}) { var testResultModel = new TestResultModel { Successful = true, ErrorMessage = "STRING" }; testResultListModel.Add(testResultModel); } return testResultListModel;
当我检查JSON结果时,它确实包含所有TestResultModel,但是TestResultListModel(TotalTestCases和TotalSuccesful)上的属性不可见。
TestResultModel
TotalTestCases
TotalSuccesful
如何将这些值也包含在JSON序列化的对象中?
我尝试使用JSON.NET属性来装饰属性[JsonProperty],但没有成功。
JSON.NET
[JsonProperty]
您的基本困难是JSON有两种类型的容器:对象和数组。从标准:
数组是值的有序集合。数组以[(左括号)开始,以(右括号)结束]。值之间用,(逗号)分隔。
[
]
,
对象是名称/值对的无序集合。对象以{(左大括号)开始,以(右大括号)结束}。
{
}
要强制对集合的属性进行序列化,请用标记[JsonObject]:
[JsonObject]
[JsonObject] public class TestResultListModel : List<TestResultModel> { public int TotalTestCases { get { return base.Count; } } public int TotalSuccessful { get { return base.FindAll(t => t.Successful).Count; } } }
当然,如果执行此操作, 则不会对项目进行序列化 ,因为JSON容器可以具有属性或项目,但不能同时具有两者。如果两者都需要,则需要添加一个合成数组属性来保存项目-如果需要,可以将其私有。
[JsonObject]还会导致Capacity您可能不希望的基类属性(例如,要序列化)。要取消基类属性,请使用MemberSerialization.OptIn。因此,您的最后一堂课应该看起来像:
Capacity
MemberSerialization.OptIn
[JsonObject(MemberSerialization = MemberSerialization.OptIn)] public class TestResultListModel : List<TestResultModel> { [JsonProperty] public int TotalTestCases { get { return base.Count; } } [JsonProperty] // Using Enumerable.Count() is more memory efficient than List.FindAll() public int TotalSuccessful { get { return this.Count(t => t.Successful); } } [JsonProperty] TestResultModel[] Items { get { return this.ToArray(); } set { if (value != null) this.AddRange(value); } } }
这提供了类似于以下内容的JSON:
{ "TotalTestCases": 4, "TotalSuccessful": 2, "Items": [ { "Successful": false, "ErrorMessage": "STRING" }, { "Successful": true, "ErrorMessage": "STRING" }, { "Successful": false, "ErrorMessage": "STRING" }, { "Successful": true, "ErrorMessage": "STRING" } ] }
由于这些属性可以在客户端轻松地重建,因此可能比其价值还多。