【问题标题】:Deserialize an Array section from within a JSON file into a List将 JSON 文件中的 Array 部分反序列化为 List
【发布时间】:2020-01-23 13:56:39
【问题描述】:

我有以下包含数据库列表/数组的有效 json,

{
        "Logging": {
            "IncludeScopes": false,
            "LogLevel": {
                "Default": "Debug"
            }
        },
        "settings": {
            "name": "",
            "path": ""

        },
        "Databases": [{
                "key1": "",
                "key2": "",
                "key3": ""
            },
            {
                "key1": "",
                "key2": "",
                "key3": ""
            }
        ]
    }

我在 C# 中使用 JsonConvert.DeserializeObject

如果还有将 json 放入 RootObject 列表的方法和类,它会很好用。

public static List<RootObject> GetConfig() {
                System.IO.StreamReader s = new StreamReader(System.IO.Directory.GetCurrentDirectory() + "\\appsettings.json");
                List<RootObject> cfg = JsonConvert.DeserializeObject<List<RootObject>>(s.ReadToEnd());
                return cfg;
            }

我现在想做的是有一个新方法,它返回一个只包含数据库的列表,(不是 json 中的日志记录、设置部分)

类似的东西

public static Databas GetDatabaseSetting(string key) {
            System.IO.StreamReader s = new StreamReader(System.IO.Directory.GetCurrentDirectory() + "\\appsettings.json");
            List<Databas> dbs = JsonConvert.DeserializeObject<List<Databas>>(s.ReadToEnd());
            foreach(var c in dbs) {
                if(c.key== key) {
                    return c;
                }
            }
            return null;
        }

但我无法让它发挥作用。

如何仅从 json 文件中的数据库设置部分创建数据库列表

【问题讨论】:

  • 手动解析appsettings.json 并不常见。当使用IConfiguration 和默认设置时,这一切都是开箱即用的。您是否有不同的要求迫使您手动解析appsettings.json
  • 你不能只说“我想要那个部分”而不反序列化整个事情。另外,是什么阻止您返回RootObject.Databases.FirstOrDefault(d =&gt; d.Key == key)?当然,这与@Kirk 所说的不同。

标签: c# json asp.net-core


【解决方案1】:

如果你在 ASP.NET Core 中使用它,你可以注册你的类

public class DatabaseCatalog
{
     List<Database> Databases { get; set; }
}

public class Database
{
    public string Key1 { get; set; }
    public string Key2 { get; set; }
    public string Key1 { get; set; }
}

然后在你的 Startup.cs 中添加

public void ConfigureServices(IServiceCollection services)
{
    IConfigurationSection dbsSection = Configuration.GetSection("Databases");
    services.Configure<DatabaseCatalog>(dbSection);
}

你可以将它注入到你的类中

public class Something
{
     private readonly DatabaseCatalog _dbsc;
     public Something(IOptions<DatabaseCatalog> dbsc)
     {
           _dbsc = dbsc.Value;
     }
}

你可以从那里分配

List<Database> dbs = _dbsc.Databases;

【讨论】:

  • 为什么它有+3? keyX 显然只是一个例子...如果会有key4...这个答案的第一部分看起来像 json 到 C# 类生成器输出
  • 键只是他应该放置的与 json 属性名称匹配的属性名称
  • 从问题中可以明显看出它们是动态的......所以使用 json2poco(或其他任何东西)输出作为答案不是一种方法
  • 老实说,这对我来说并不明显,但如果是这样,那么他必须使用反射来查看 json 中的属性名称是否匹配,以便他可以反序列化它们
  • @Selvin 我同意@Mycenaean。在appsettings.json 中有动态属性看起来很奇怪。我想建议使用 json2poco 方法并向 Database 类添加一个数组而不是变量列表,例如 "Databases": [{"Keys":["value1", "value2", ... ]}] 和 poco 对象,例如 class Database { public string[] Keys {get; set; } }
【解决方案2】:

您可以使用 Linq 进行后反序列化

public static Database GetDatabaseSetting(string key, IEnumerable<RootObject> objects) 
{
    return objects.SelectMany(o => o.Databases).SingleOrDefault(d => d.Key == key);
}

但正如 Kirk 所问的那样:处理 appsettings.json,通常您会使用可用的开箱即用连接字符串:

{
    "Logging": {...}
    "ConnectionStrings": { "BloggingDatabase": "connection string here" }
}

在启动时使用:

Configuration.GetConnectionString("BloggingDatabase");

如果你想在其他服务中使用它,你可以传递一个 IConfiguration 依赖。

见:https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-strings

【讨论】:

    【解决方案3】:
    IConfigurationSection dbArraySection = _config.GetSection("Databases");
    
    var dbArray = dbArraySection.AsEnumerable();
    

    【讨论】:

      【解决方案4】:
      public class DBObj
      {
          public List<Item> Databases { get; set; }
      }
      
      public class Item
      {
          public string Key1 { get; set; }
          public string Key2 { get; set; }
          public string Key3 { get; set; }
      }
      

      然后

      var db = JsonConvert.DeserializeObject<DBObj>(json);
      

      【讨论】:

        猜你喜欢
        • 2018-10-06
        • 1970-01-01
        • 2018-01-09
        • 2021-06-14
        • 2015-06-07
        • 1970-01-01
        • 2017-08-15
        • 1970-01-01
        • 2017-02-28
        相关资源
        最近更新 更多