【问题标题】:Update a json file containing variables from another json file in C#在 C# 中更新包含来自另一个 json 文件的变量的 json 文件
【发布时间】:2021-09-03 14:14:05
【问题描述】:

我有一个带有值作为变量的 json 配置文件。我想用存储在另一个 json 文件中的实际值替换这些变量。

源数据json文件:

{
  "person": {
    "id": 15305,
    "gender": "Male",
    "dob": "1958-10-31T00:00:00",
    "name": {
      "id": 80587,
      "first": "John",
      "last": "Dominick"
    }
  },
  "ethnicity": [
    {
      "id": 2,
      "display": "Not Hispanic or Latino",
      "kbEthnicity": null
    }
  ],
  "race": [
    {
      "id": 4,
      "display": "Black"
    },
    {
      "id": 6,
      "display": "Other Race"
    }
  ]
}

目的地数据json文件:

{
  "dryRun": "true",
  "person": {
    "firstName": "[person.name.first]",
    "lastName": "[person.name.last]",
    "dateOfBirth": "[person.dob]",
    "gender": "[person.gender]",
    "race": "[race]"
  }
}

我想要的最终 json 文件: { “dryRun”:“真”, “人”: { "firstName": "约翰", "lastName": "多米尼克", "dateOfBirth": "1958-10-31T00:00:00", “性别”:“男性”, “种族”:“黑人,其他种族” } }

这是我使用以下 SO post 编写的代码,它读取两个文件并能够从源文件中提取正确的值,但我一直坚持创建最终 json 文件的最佳方法是什么.

public static void  Main(string[] args)
{
    var sourceJson = File.ReadAllText("./sourcedata.json");
    var srcObj = JObject.Parse(sourceJson);
    var destJson = File.ReadAllText("./destinationdata.json");
    var destObj = JObject.Parse(destJson);

    var result = destObj.Descendants()
        .OfType<JProperty>()
        .Select(p => new KeyValuePair<string, object>(p.Path,
            p.Value.Type == JTokenType.Array || p.Value.Type == JTokenType.Object
                ? null : p.Value));

    foreach (var kvp in result)
    {
        var isVariable = kvp.Value == null ? false : Regex.IsMatch(kvp.Value.ToString(), @"^\[.*?\]$");
        if (isVariable)
        {
            var variable = Regex.Replace(kvp.Value.ToString(), @"[\[\]]+", "");
            Console.WriteLine($"Key: {kvp.Key}  Value: {kvp.Value}  Updated: {srcObj.SelectToken(variable)}");
        }
        else
        {
            Console.WriteLine($"Key: {kvp.Key}  Value: {kvp.Value}");
        }
    }               
}

我要解决的另一个问题是如果存在数组,如何连接这些值?任何帮助将不胜感激。

【问题讨论】:

  • 作为一名 C# 用户,我经常在 Web 项目中遇到这类 JSON 处理任务,这些任务通常也是一次性的;即一旦结果 JSON 文件完成,代码也是如此。我个人使用 node.js 来完成这类任务,因为 JS 确实非常适合处理 JSON,而且几乎不需要大惊小怪。虽然有很多变量,例如你知道JS等吗,但无论如何只是一个建议。
  • @LukeBriggs 我同意你的观点,但 JSON 正在成为一种通用格式,所有语言都在更好地配备库来处理它们。我本来会使用 JS,但我现在被困在 C# 来完成这项任务,因为它是我正在尝试更新的现有 Web API 代码的一部分。但是,我听到了。

标签: c# json


【解决方案1】:

高级:您需要两个 POCO 对象:一个用于反序列化源 json(带有值),另一个用于序列化到目标 json。

你读入源代码,反序列化为源 poco,从源 poco 转换为目标 poco,然后将 that 序列化为目标 json。

我认为这比使用JObjects 等要简单得多。

这是您的对象的略微简化版本:

using System;
using Newtonsoft.Json;
                    
public class Program
{
    public static void Main()
    {
        var json = @"{""person"":{""name"": {""first"": ""John"",""last"": ""Dominick""}}}";

        var objA = Newtonsoft.Json.JsonConvert.DeserializeObject<Source.MyObject>(json);
        Console.WriteLine("FirstName: " + objA.Person.Name.FirstName);
        
        var objB = new Destination.MyObject(objA);
        var outJson = Newtonsoft.Json.JsonConvert.SerializeObject(objB);
        Console.WriteLine(outJson);
        
    }
}
public class Source{
    public class MyObject
        {
            [JsonProperty("person")]
            public Person Person { get; set; }
        }
    public class Person
        {
            [JsonProperty("name")]
            public Name Name { get; set; }
        }
    public class Name
        {
            [JsonProperty("first")]
            public string FirstName { get; set; }

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

public class Destination{
    public class MyObject{
        public MyObject(Source.MyObject sourceObject){
            Person = new Person();
            Person.FirstName = sourceObject.Person.Name.FirstName;
            Person.LastName = sourceObject.Person.Name.LastName;
        }

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

    public class Person
    {
        [JsonProperty("firstName")]
        public string FirstName {get;set;}

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

输出:

名字:约翰 {"person":{"firstName":"John","lastName":"Dominick"}}

见: https://dotnetfiddle.net/0V4pEO

【讨论】:

  • 感谢您的及时回复。我错过了一个重要方面,那就是子字符串不是固定的,正如帖子中提到的,这些 json 是配置,所以我们可以有不同的 json。很遗憾,我不能使用 POCO。
猜你喜欢
  • 1970-01-01
  • 2019-12-09
  • 2021-08-19
  • 2014-09-18
  • 2021-07-06
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多