【问题标题】:Newtonsoft.JSON, Deserialize different JSON fields that similar into single type, but will have different deserialized object fieldNewtonsoft.JSON,将相似的不同JSON字段反序列化为单一类型,但将具有不同的反序列化对象字段
【发布时间】:2019-03-03 20:18:15
【问题描述】:

我有一个 JSON 字段或多或少看起来像这样

{
    "Photos" : 
    [
        {
            "file_id" : "Some value",
            "type" : "Some certain value",
            /*'Photo's specific fields*/
        },
        {
            "file_id" : "Some value",
            "type" : "Some certain value",
            /*'Photo's specific fields*/
        },
        {
            "file_id" : "Some value",
            "type" : "Some certain value",
            /*'Photo's specific fields*/
        }

    ],
    "Document" : 
    {
        "file_id" : "Some value",
        "type" : "Some certain value",
        /*'Document's specific fields*/
    },
    "Video" : 
    {
        "file_id" : "Some value",
        "type" : "Some certain value",
        /*'Video's specific fields*/
    },
}

整个 JSON 将被反序列化到这个类中

public class APIResponse
{
    [JsonProperty(PropertyName = "Photos")]
    public List<APIFile> Photos;

    [JsonProperty(PropertyName = "Document")]
    public APIFile Document;

    [JsonProperty(PropertyName = "Video")]
    public APIFile Video;
}

APIFile 是一个类,它是每个 JSON 字段反序列化的“目标类型”,它看起来像这样

public class APIFile
{
    public enum FileMIME
    {
        // Some already specified enum values
    }
    [JsonProperty(PropertyName = "file_id")]
    public string FileID;
    [JsonProperty(PropertyName = "type")]
    public string FileType;
    [JsonIgnore()]
    public FileMIME MIMEType;
}

如您所见,JSON 中的这三个字段共享一些公共字段,file_id 和 type,其中 Photos 是某些类型的集合,它们也共享相同的公共字段。

问题是,我怎样才能反序列化它们中的每一个,但将MIMEType 字段分别设置为反序列化字段?最好不要使用JsonConverter 或添加额外的类

例如,当它反序列化 JSON 字段 Document 时,将创建 APIResponse 对象中的字段 Document MIMEType 字段的值为 MIMEType.Document

【问题讨论】:

  • 为什么不让APIFile成为一个抽象基类,并将其子类化为APIPhoto、APIVideo、APIDocument等等?
  • 我正在尝试减少为满足此 JSON 模式要求而必须创建的类的数量,并且我真的不需要每种类型的其余字段 It's Telegram Bot API BTW ,尝试访问 API 页面,查看“可用类型”,它非常庞大且非常非常嵌套(至少对我而言)

标签: c# json json.net


【解决方案1】:

您可以使用带有支持私有字段的设置器:

    public enum FileMIME
    {
        Document,
        Photos,
        Video       
    }

    public class APIResponse
    {
        private List<APIFile> _photos;
        [JsonProperty(PropertyName = "Photos")]
        public List<APIFile> Photos
        {
            get { return _photos; }
            set {   _photos = value;
                    foreach(var photo in _photos)
                    {
                        photo.MIMEType = FileMIME.Photos;
                    }
                }
        }

        private APIFile _document;
        [JsonProperty(PropertyName = "Document")]
        public APIFile Document
        {
            get { return _document; }
            set { _document = value; _document.MIMEType = FileMIME.Document; }
        }

        private APIFile _video;
        [JsonProperty(PropertyName = "Video")]
        public APIFile Video
        {
            get { return _video; }
            set { _video = value; _video.MIMEType = FileMIME.Video; }
        }
    }

【讨论】:

  • 我明白了,从没想过setter 可以这样使用,但糟糕的是它需要支持值。不过,不管我不必创建单独的转换器
  • 另外一个,我可以做类似value.MIME = MIMEType.Video 然后做_video = value 或者我只能在value 分配给back-val 之后的支持值吗?跨度>
【解决方案2】:

您可以使用 Dictionary&lt;string, object&gt; 代替 APIFile 类。然后,您可以在返回响应之前将 FileMIME 添加到每个字典。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2019-05-27
    • 1970-01-01
    • 2019-12-29
    相关资源
    最近更新 更多