【问题标题】:Deserializing a string property value to a class instance using JSON.Net使用 JSON.Net 将字符串属性值反序列化为类实例
【发布时间】:2019-02-22 14:30:30
【问题描述】:

我正在从服务器反序列化一些 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'


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

【问题讨论】:

    标签: c# json json.net deserialization implicit-conversion


    【解决方案1】:

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

    如果我们修改 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;
    
    }
    

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

    【讨论】:

    • 感谢您的想法。这是了解 JSON.Net 工作原理的一个不错的解决方法。我仍然希望对 JSON.Net 有更深入了解的人有更优雅的解决方案。
    • 是的,据我所知,这似乎是最直接的工作。我想它最终会成为一个自定义序列化程序。
    【解决方案2】:

    目前我正在使用@Jlalonde 建议的以下变体 - 进行了调整,以便用户体验不会改变,利用 JSON.NET 也寻找私有属性这一事实。

    public class Example
    {
        public string id { get; set; }
        public int number { get; set; }
        [JsonIgnore]
        public Perspective configured_perspective { get; set; }
        [DataMember(Name = "configured_perspective")]
        private string configured_perspective_serialized
        {
            get => configured_perspective?.ToString();
            set => configured_perspective = value == null ? null : new Perspective(value);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-24
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      相关资源
      最近更新 更多