当前位置: 首页 > 面试题库 >

JSON对类继承列表上的属性进行序列化

戚俊健
2023-03-14
问题内容

我有一个模型如下:

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

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,但是TestResultListModelTotalTestCasesTotalSuccesful)上的属性不可见。

如何将这些值也包含在JSON序列化的对象中?

我尝试使用JSON.NET属性来装饰属性[JsonProperty],但没有成功。


问题答案:

您的基本困难是JSON有两种类型的容器:对象和数组。从标准:

  • 数组是值的有序集合。数组以[(左括号)开始,以(右括号)结束]。值之间用,(逗号)分隔。

  • 对象是名称/值对的无序集合。对象以{(左大括号)开始,以(右大括号)结束}

要强制对集合的属性进行序列化,请用标记[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。因此,您的最后一堂课应该看起来像:

[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"
    }
  ]
}

由于这些属性可以在客户端轻松地重建,因此可能比其价值还多。



 类似资料:
  • 问题内容: 我正在尝试仅使用json.net序列化类的继承属性。我知道[JsonIgnore]属性,但是我只想在某些情况下忽略它们,因此我改用了自定义JsonConverter。 这是我的课: 做一个简单的o.WriteTo(writer); 它给出的结果与不使用转换器的结果相同。当遍历属性并在属性上使用WriteTo时,它对于基本类型(int,字符串等)正常工作,但是集合存在问题。 预期: 得到

  • 假设我有一个这样的POJO: 我希望创建一个自定义序列化程序来输出以下内容: 但这里有一个问题,它不是特定于POJO1的。这意味着对另一个POJO进行相同的序列化: 或者任何具有 TypeA 或 TypeB 属性的类,这意味着这些方法可以更改。我不喜欢以基类或接口为目标,因为我的序列化程序将被开发我从未想象过的其他类的人使用。我一直在考虑注册TypeA和TypeB序列化程序,但它们似乎不允许我更改

  • 问题内容: 我有一个清单清单: 如果要按一个元素(例如,高/短元素)排序,可以通过进行。 如果我想作为排序依据两个高大和颜色,我可以为每个元素做排序两次,一次,但有一个更快的方法? 问题答案: 键可以是返回元组的函数: 或者,你可以使用来实现相同的效果(速度更快,并且避免了Python函数调用): 并请注意,你可以在此处使用而不是使用,然后重新分配:

  • 问题内容: 假设您有Foo和Bar这两个类,其中Bar扩展了Foo并实现了 注意,Foo没有实现。那么当bar序列化时会发生什么? 它会显示“默认21”。问题是,为什么在未序列化类时调用默认构造函数? 问题答案: 可序列化只是给定类的“标记接口”。 但是该类必须遵守某些规则: http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializ

  • 问题内容: 比方说你有一个的对象。 如果它们都具有int GoalScored变量,则如何排序?你如何按GoalScored排序? 问题答案: 你可以使用Collections.sort自定义Comparator 。 比较部分也可以这样写: 或者,你可以制作。这定义了所有对象的自然顺序。使用a 更灵活,因为不同的实现可以按名称,年龄等进行排序。

  • 如何按照一个属性的字母顺序(不是名称,而是属性所包含的实际值)对一个对象列表进行排序?