【问题标题】:Serialize/Deserialize Json Object class structure [duplicate]序列化/反序列化 Json 对象类结构 [重复]
【发布时间】:2021-08-18 19:51:03
【问题描述】:

提前谢谢你。我真的坚持这一点,但练习。提前感谢您的帮助。

我能够在我的代码中成功构建这个 Json 对象,但是使用我用来构建它的同一个字典对其进行反序列化,它不起作用,因为定义的字符串类型是匿名的,我无法专门访问子项 (包含、等于、startsWith)。

我的 json 已成功构建,但在反序列化时再次不起作用。

{
"shortDescription": {
  "contains": false,
  "equals": false,
  "startsWith": true,
  "value": "some text"
},
"description": {
  "contains": true,
  "equals": false,
  "startsWith": false,
  "value": "some more text"
},
"createdAfter": {
  "contains": false,
  "equals": false,
  "startsWith": false,
  "value": "2021-08-17"
},
"notes": "Something bad happened",
"group": "some group",
"assigned": "to me"
}

这些对象(如 shortDescription)甚至可能不存在,具体取决于用户选择,这就是为什么我使用“String”构建匿名类型字典的原因 public Dictionary properties { get;放;我可以将此格式应用于需要这些属性的任何对象。

public class filter_keys
{
    public string notes { get; set; }
    public string group { get; set; }
    public string assigned { get; set; }
    public Dictionary<string, filter_properties> properties { get; set; }
}
public class filter_properties
{
    public bool contains { get; set; }
    public bool equals { get; set; }
    public bool startsWith { get; set; }
    public string value { get; set; }
}

我真的很感激一些帮助,以弄清楚如何仅为此描述和 shortDescription 字段设置一个简单的属性,不仅可以序列化数据,还可以反序列化数据,因此我可以检查这些对象是否存在在json中。

当我设置我使用的 json 时

Dictionary<string, filter_properties> keys = new Dictionary<string, filter_properties>();

keys.Add("anonymous", new filter_properties { value="can't find it" });

和/或

keys.Add("shortDescription", new filter_properties { 
                        contains = true, 
                        value = "blah blah blah"
                    });

【问题讨论】:

  • 您的问题是可能的属性集(例如shortDescription)甚至可能不存在,或者可能的属性集在前进并且是无限的
  • 你能详细说明is not working吗?也可以分享一下序列化和反序列化的代码吗?
  • 该字典对象属性在您的 POCO 类中称为 properties,但在 json 中,shortDescriptiondescriptioncreatedAfter 都在根目录中,而不是在 @987654332 下@节点。如果您重建 json 以将这三个放在 properties 节点下会发生什么?
  • 如果您的根对象混合了固定属性(例如notesgroup)以及一组其值具有固定架构的可变属性,此处为filter_properties,您可以使用[JsonTypedExtensionData] public Dictionary&lt;string, filter_properties&gt; properties { get; set; },其中[JsonTypedExtensionData] 及其关联的TypedExtensionDataConverter&lt;filter_keys&gt; 来自How to deserialize a child object with dynamic (numeric) key names?

标签: c# json serialization object-class


【解决方案1】:

就像我在评论中提到的那样,您必须在 properties 节点下使用这些属性构建您的 json。

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        var inJson = @"{
        ""properties"": {
            ""shortDescription"": {
              ""contains"": false,
              ""equals"": false,
              ""startsWith"": true,
              ""value"": ""some text""
            },
            ""description"": {
              ""contains"": true,
              ""equals"": false,
              ""startsWith"": false,
              ""value"": ""some more text""
            },
            ""createdAfter"": {
              ""contains"": false,
              ""equals"": false,
              ""startsWith"": false,
              ""value"": ""2021-08-17""
            }
        },
        ""notes"": ""Something bad happened"",
        ""group"": ""some group"",
        ""assigned"": ""to me""
        }";
        
        var deserialized = JsonConvert.DeserializeObject<filter_keys>(inJson);
        Console.WriteLine(deserialized.notes);
        foreach(var prop in deserialized.properties)
        {
            Console.WriteLine(prop.Key);
            Console.WriteLine(prop.Value.value);
        }
    }

    public class filter_keys
    {
        public string notes { get; set; }
        public string group { get; set; }
        public string assigned { get; set; }
        public Dictionary<string, filter_properties> properties { get; set; }
    }
    public class filter_properties
    {
        public bool contains { get; set; }
        public bool equals { get; set; }
        public bool startsWith { get; set; }
        public string value { get; set; }
    }
}

见:

https://dotnetfiddle.net/bdGTmf

【讨论】:

    【解决方案2】:

    我听从了乔纳森的指导,你当然是对的。我只是为每个项目添加了一个显式键,而不是使用通用键。

    public class filter_keys
    {
        public string info { get; set; }
        public string dec { get; set; }
        public string assigned { get; set; }
        public string state { get; set; }
        public string target { get; set; }
        public string caller { get; set; }
        public filter_properties shortDescription { get; set; }
        public filter_properties description { get; set; }
        public filter_properties status { get; set; }
        public DateTime date1 { get; set; }
        public DateTime date2 { get; set; }
        public DateTime date3 { get; set; }
        public DateTime date4 { get; set; }
    }
    public class filter_properties
    {
        public bool contains { get; set; }
        public bool equals { get; set; }
        public bool startsWith { get; set; }
        public bool isNot { get; set; }
        public string _value { get; set; }
    }
    

    实施

    filter_keys keys = new filter_keys();
    
    filter_properties = new filter_properties { 
                                contains = true,
                                _value = descriptionTxt.Text
                        };
    keys.description = filter_properties;
    

    一切都很好地序列化和反序列化。

    string filters = (string)Session["incidentRequest"];
    
    if (!string.IsNullOrEmpty(filters))
    {
       // for lates version of newtonsoft.json nulls cause error. Add null value handling
       filter_keys filter_values = JsonConvert.DeserializeObject<filter_keys>(filters, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
    
       query += "group=" + filter_values.target;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多