首页 > 解决方案 > 使用 JSON.Net 将字符串属性值反序列化为类实例

问题描述

我正在从服务器反序列化一些 JSON,这在大多数情况下很简单:

{
    "id": "ABC123"
    "number" 1234,
    "configured_perspective": "ComplexPerspective[WithOptions,Encoded]"
}

然而,“configured_perspective”属性是服务器使用奇怪的组合字符串的不幸情况,而嵌套对象会更好。

为了减轻 .NET 用户的痛苦,我将其转换为对象模型中的自定义类:

public class Example
{
    public string id { get; set; }
    public int number { get; set; }
    public Perspective configured_perspective { get; set; }
}

// Note, instances of this class are immutable
public class Perspective
{
    public CoreEnum base_perspective { get; }
    public IEnumerable<OptionEnum> options { get; }

    public Perspective(CoreEnum baseArg, IEnumerable<OptionEnum> options) { ... }
    public Perspective(string stringRepresentation) {
        //Parses that gross string to this nice class
    }
    public static implicit operator Perspective(string fromString) =>
        new Perspective(fromString);
    public override string ToString() =>
        base_perspective + '[' + String.Join(",", options) + ']';
}

如您所见,我已经组合了一个自定义类Perspective,它可以在 JSON 字符串之间进行转换,但我似乎无法让 Newtonsoft JSON 自动将字符串转换为我的 Perspective 类。


我尝试让它使用[JsonConstructor]属性调用字符串构造函数,但它只是使用 调用构造函数null,而不是使用 JSON 中存在的字符串值。

我的印象是(基于https://stackoverflow.com/a/34186322/529618)JSON.NET将使用隐式/显式字符串转换运算符将 JSON 中的简单字符串转换为目标类型的实例(如果可用) ,但它似乎忽略了它,只返回错误:

Newtonsoft.Json.JsonSerializationException:找不到用于透视类型的构造函数。一个类应该有一个默认构造函数、一个带参数的构造函数或一个标有 JsonConstructor 属性的构造函数。路径'configured_perspective'


我试图避免为我的班级编写自定义 JsonConverter Example- 我很确定会有一种开箱即用的方法将简单的字符串值转换为非字符串属性类型,我只是没有还没有找到。

标签: c#jsonjson.netdeserializationimplicit-conversion

解决方案


在阅读您的最后一篇文章之前,我实际上编写了一个自定义序列化程序类,但后来我有了一个想法。

如果我们修改 example 以不将其序列化为 Perspective 怎么办?我们对此有点懒惰?

public class Example 
{
    public string id { get; set; }
    public int number { get; set; }
    public string configured_perspective { get; set; }
    private Perspective _configuredPespective;
    [JsonIgnore]
    public Perspective ConfiguredPerspective => _configuredPerspective == null ? new Perspective(configured_persective) : _configuredPerspective;

}

它并不完美,我们坚持使用浪费内存的字符串,但它可能对您有用。


推荐阅读