使用数组和JsonConverter阅读复杂配置的ASP NET内核

smdnsysy  于 2023-02-10  发布在  其他
关注(0)|答案(1)|浏览(98)

我有这个appsettings.json

"TopLevel": [
    {
      "Name": "Name",
      "TopChild": {
        "File": {
          "URL": "SomeUrl",
          "Username": "Admin",
          "Password": "123"
        }
      },
      "TopChild2": [
        {
          "Name": "SimpleMapper",
          "Mapper": {
            "Param1": "",
            "Param2": "",
            "Param3": ""
          }
        },
        {
          "Name": "SimpleFileConverter",
          "Converter": {
            "ToWhat": "",
            "Writer": ""
          }
        }
      ],
      "TopChild3": {
        "SomeProperty3": {
          "WhatIsThis": "",
          "SomeProp": "",
          "Password": ""
        }
      }
    },
    {
      "Name": "Name",
      "TopChild": {
        "DB": {
          "ConnectionString": "String",
          "Username": "Admin",
          "Password": "123"
        }
      },
      "TopChild2": [
        {
          "Name": "SomeConverter",
          "Converter": {
            "Param1": "",
            "Param2": ""
          }
        },
        {
          "Name": "SimpleFileConverter",
          "Mapper": {
            "Param1": "",
            "Param2": "",
            "Param3": ""
          }
        }
      ],
      "TopChild3": {
        "SomePropety4": {
          "SomeProp7": "",
          "Password": ""
        }
      }
    }
  ]

这是我为一个模型写的代码

public class TopLevelConfigRoot
        {
            [JsonProperty("TopLevel")]
            public List<TestObject> TopLevel { get; set; }
        }

        public class TestObject
        {
            [JsonProperty("Name")]
            public string Name { get; set; }

            [JsonProperty("TopChild")]
            [JsonConverter(typeof(TopChildConverter))]
            public TopChildBase TopChild { get; set; }

            [JsonProperty("TopChild2")]
            [JsonConverter(typeof(TopChild2Converter))]
            public List<TopChild2> TopChild2 { get; set; }

            [JsonProperty("TopChild3")]
            [JsonConverter(typeof(TopChild3Converter))]
            public TopChild3Base TopChild3 { get; set; }
        }

        public abstract class TopChildBase { }
        public abstract class TopChild3Base { }

        public class File : TopChildBase
        {
            [JsonProperty("URL")]
            public string URL { get; set; }

            [JsonProperty("Username")]
            public string Username { get; set; }

            [JsonProperty("Password")]
            public string Password { get; set; }
        }

        public class DB : TopChildBase
        {
            [JsonProperty("ConnectionString")]
            public string ConnectionString { get; set; }

            [JsonProperty("Username")]
            public string Username { get; set; }

            [JsonProperty("Password")]
            public string Password { get; set; }
        }

        public interface ITopChild2
        {
            public string Name { get; set; }
            public ITopChild2Type ITopChild2Type { get; set; }
        }

        public class TopChild2 : ITopChild2
        {
            [JsonProperty("Name")]
            public string Name { get; set; }

            [JsonProperty("ITopChild2Type")]
            public ITopChild2Type ITopChild2Type { get; set; }
        }

        public abstract class ITopChild2Type
        { }

        public class Mapper : ITopChild2Type
        {
            [JsonProperty("Param1")]
            public string Param1 { get; set; }

            [JsonProperty("Param2")]
            public string Param2 { get; set; }

            [JsonProperty("Param3")]
            public string Param3 { get; set; }
        }

        public class Converter : ITopChild2Type
        {
            [JsonProperty("Param1")]
            public string Param1 { get; set; }

            [JsonProperty("Param2")]
            public string Param2 { get; set; }
        }

        public class SomeProperty3 : TopChild3Base
        {

            [JsonProperty("WhatIsThis")]
            public string WhatIsThis { get; set; }

            [JsonProperty("SomeProp")]
            public string SomeProp { get; set; }

            [JsonProperty("Password")]
            public string Password { get; set; }
        }

        public class SomePropety4 : TopChild3Base
        {
            [JsonProperty("SomeProp7")]
            public string SomeProp7 { get; set; }

            [JsonProperty("Password")]
            public string Password { get; set; }

        }

        public class TopChildConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return objectType == typeof(TopChildBase);
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JObject jo = JObject.Load(reader);

                if (jo.ContainsKey(nameof(File)))
                {
                    return jo[nameof(File)].ToObject<File>();
                }
                else if (jo.ContainsKey(nameof(DB)))
                {
                    return jo[nameof(DB)].ToObject<DB>();
                }
                return null;
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        public class TopChild3Converter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return objectType == typeof(TopChild3Base);
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JObject jo = JObject.Load(reader);

                if (jo.ContainsKey(nameof(SomeProperty3)))
                {
                    return jo[nameof(SomeProperty3)].ToObject<SomeProperty3>();
                }
                else if (jo.ContainsKey(nameof(SomePropety4)))
                {
                    return jo[nameof(SomePropety4)].ToObject<SomePropety4>();
                }
                return null;
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        public class TopChild2Converter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return objectType == typeof(TopChild2);
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JArray ja = JArray.Load(reader);

                List<TopChild2> topChild2List = new List<TopChild2>();
                foreach (var item in ja)
                {
                    JObject jObject = (JObject)item;

                    TopChild2 TopChild2 = null;

                    string name = jObject[nameof(TopChild2.Name)].ToString();

                    if (jObject.ContainsKey(nameof(Mapper)))
                    {
                        var root = jObject[nameof(Mapper)];

                        Mapper mapper = new Mapper
                        {
                            Param1 = root[nameof(Mapper.Param1)].Value<string>(),
                            Param2 = root[nameof(Mapper.Param2)].Value<string>(),
                            Param3 = root[nameof(Mapper.Param3)].Value<string>()
                        };

                        TopChild2 = new TopChild2 { Name = name, ITopChild2Type = mapper };
                    }
                    else if (jObject.ContainsKey(nameof(Converter)))
                    {
                        var root = jObject[nameof(Converter)];

                        Converter converter = new Converter
                        {
                            Param1 = root[nameof(Converter.Param1)].Value<string>(),
                            Param2 = root[nameof(Converter.Param2)].Value<string>()
                        };

                        TopChild2 = new TopChild2 { Name = name, ITopChild2Type = converter };
                    }

                    topChild2List.Add(TopChild2);
                }
                return topChild2List;
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

现在,在这个模型中,我尝试使用控制器中任何已知的config实现。
我唯一想到的是通过依赖注入和use _config = config插入IConfiguration;
然后选择它

var section = _config.GetSection("TopLevel");

然后像这样

var itemArray = section.AsEnumerable();

然后,我如何使用这个itemArray将其转换为模型或JsonString,然后使用Newtonsoft轻松地将其序列化

var t = JsonConvert.DeserializeObject<TopLevelConfigRoot>(jsonString);

但是我还没有找到一种方法将这个itemArrayMap到我提供的模型,也没有成功地编写递归方法将它实际Map到JsonString。
我写的转换器是

public string ConvertBackToJSonString(KeyValuePair<string, string>[] itemArray)
    {
        var root = new JObject();
        var current = root;

        foreach (var item in itemArray)
        {
            var parts = item.Key.Split(':');
            var key = parts[parts.Length - 1];
            var parent = current;

            for (int i = 0; i < parts.Length - 1; i++)
            {
                var part = parts[i];
                if (!current.ContainsKey(part))
                    current.Add(part, new JObject());
                current = (JObject)current[part];
            }

            if (!string.IsNullOrEmpty(item.Value))
                current.Add(key, new JValue(item.Value));
            else
                current.Add(key, new JObject());

            current = parent;
        }

        return JsonConvert.SerializeObject(root, Formatting.Indented);
    }

但那不起作用。应该如何着手/做呢?

8xiog9wr

8xiog9wr1#

您可以使用IConfigration.bind()方法直接将节绑定到模型
例如,在您的情况下:

public class BindTarget
    {
        public string Name { get; set; }

        public SomeChildClass1 TopChild { get; set; }
        public List<SomeChildClass2> TopChild2 { get; set; }
        public SomeChildClass3 TopChild3 { get; set; }

    }

    public class SomeChildClass1
    {
        public File File { get; set; }
        public DB  DB { get; set; }
    }
    public class SomeChildClass2
    {
        public string Name { get; set; }
        public Mapper Mapper { get; set; }

        public Converter Converter { get; set; }
    }
    public class SomeChildClass3
    {
        public SomeProperty3 SomeProperty3 { get; set; }
        public SomePropety4 SomePropety4 { get; set; }
    }

约束如下:

var targetobj = new List<BindTarget>();
Configuration.GetSection("TopLevel").Bind(targetobj);
var str = JsonConvert.SerializeObject(targetobj,new JsonSerializerSettings() { NullValueHandling=NullValueHandling.Ignore});

结果:

相关文件

相关问题