使用C#基于System.Text.Json实现多格式JSON转通用结构
使用System.Text.Json实现供应商JSON到通用Person结构的转换
下面提供两种可行的实现方案,适配你的需求:
方案一:基于JSON DOM(JsonDocument)的灵活转换
这种方法无需定义输入模型,直接解析JSON节点进行映射,适合结构多变的场景:
using System.Text.Json; // 定义目标通用模型 public class Person { [JsonPropertyName("First_Name")] public string FirstName { get; set; } [JsonPropertyName("Last_Name")] public string LastName { get; set; } } public class PersonRoot { [JsonPropertyName("Person")] public List<Person> People { get; set; } } public static PersonRoot ConvertToPersonJson(string vendorJson) { var personList = new List<Person>(); using var doc = JsonDocument.Parse(vendorJson); var root = doc.RootElement; // 遍历根节点下的所有属性,找到数组类型的节点(Students/Employee) foreach (var property in root.EnumerateObject()) { if (property.Value.ValueKind == JsonValueKind.Array) { foreach (var item in property.Value.EnumerateArray()) { var person = new Person(); // 根据不同的字段名映射 if (item.TryGetProperty("FirstName", out var firstName)) { person.FirstName = firstName.GetString(); person.LastName = item.GetProperty("LastName").GetString(); } else if (item.TryGetProperty("FName", out var fName)) { person.FirstName = fName.GetString(); person.LastName = item.GetProperty("LName").GetString(); } personList.Add(person); } } } return new PersonRoot { People = personList }; } // 使用示例 string studentJson = @"{""Students"": [{""FirstName"":""Abc"",""LastName"":""pqr""},{""FirstName"":""pqr"",""LastName"":""pqccr""}]}"; string employeeJson = @"{""Employee"": [{""FName"":""Abc"",""LName"":""pqr""},{""FName"":""pqr"",""LName"":""pqccr""}]}"; var studentPerson = ConvertToPersonJson(studentJson); var employeePerson = ConvertToPersonJson(employeeJson); // 序列化输出目标JSON string targetJson = JsonSerializer.Serialize(studentPerson, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(targetJson);
方案二:基于强类型模型的转换
如果供应商的JSON结构稳定,这种方法类型更安全:
using System.Text.Json; using System.Text.Json.Serialization; // 目标通用模型 public class Person { [JsonPropertyName("First_Name")] public string FirstName { get; set; } [JsonPropertyName("Last_Name")] public string LastName { get; set; } } public class PersonRoot { [JsonPropertyName("Person")] public List<Person> People { get; set; } } // 定义供应商输入模型 public class Student { [JsonPropertyName("FirstName")] public string FirstName { get; set; } [JsonPropertyName("LastName")] public string LastName { get; set; } } public class StudentRoot { [JsonPropertyName("Students")] public List<Student> Students { get; set; } } public class Employee { [JsonPropertyName("FName")] public string FirstName { get; set; } [JsonPropertyName("LName")] public string LastName { get; set; } } public class EmployeeRoot { [JsonPropertyName("Employee")] public List<Employee> Employees { get; set; } } public static PersonRoot ConvertToPersonJson(string vendorJson) { PersonRoot result = new PersonRoot { People = new List<Person>() }; // 先尝试反序列化为学生模型 try { var studentRoot = JsonSerializer.Deserialize<StudentRoot>(vendorJson); if (studentRoot?.Students != null) { result.People.AddRange(studentRoot.Students.Select(s => new Person { FirstName = s.FirstName, LastName = s.LastName })); return result; } } catch (JsonException) { // 不是学生JSON,继续尝试员工模型 } // 尝试反序列化为员工模型 try { var employeeRoot = JsonSerializer.Deserialize<EmployeeRoot>(vendorJson); if (employeeRoot?.Employees != null) { result.People.AddRange(employeeRoot.Employees.Select(e => new Person { FirstName = e.FirstName, LastName = e.LastName })); return result; } } catch (JsonException) { throw new InvalidOperationException("输入JSON不符合学生或员工结构"); } return result; } // 使用示例 string studentJson = @"{""Students"": [{""FirstName"":""Abc"",""LastName"":""pqr""},{""FirstName"":""pqr"",""LastName"":""pqccr""}]}"; var targetJson = JsonSerializer.Serialize(ConvertToPersonJson(studentJson), new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(targetJson);
注意事项
- 两种方案都支持
WriteIndented选项来生成格式化的JSON,和你示例中的格式一致。 - 如果后续有更多供应商结构,只需在映射逻辑中添加对应的字段判断(方案一)或新增输入模型(方案二)即可扩展。
内容的提问来源于stack exchange,提问作者Prasad Gavande
相关产品推荐
相关产品推荐

