首页 > 解决方案 > 将动态 json 反序列化为通用 .NET 对象

问题描述

将以下 JSON 响应反序列化为通用对象的最佳方法是什么?例如,我想访问响应消息和错误列表(并访问它的字段名称和错误消息)。

{
  "message": "The given data was invalid.",
  "errors": {
      "name": [
          "Name is required."
      ],
      "gender": [
          "Gender is required."
      ],
      "date_of_birth": [
          "Date of birth is required."
      ]
  }
}

编辑:

我想以这样的方式访问 JSON 对象

string message = genericObject.message
foreach (error errorElement in genericObject.errors)
{
  string errorField = errorElement.fieldName;
  string errorDescription = errorElement.errorMessage;
}

编辑2:

我事先不知道可能的错误字段。

标签: c#.netjsonjson.net

解决方案


由于您提到您不知道将出现哪些“错误字段”,因此字典是最好的方法。

这是一个简单的例子:

void Main()
{
    string json = File.ReadAllText(@"d:\temp\test.json");
    var response = JsonConvert.DeserializeObject<Response>(json);
    response.Dump();
}

public class Response
{
    public string Message { get; set; }

    public Dictionary<string, List<string>> Errors { get; }
        = new Dictionary<string, List<string>>();
}

LINQPad中执行此操作时,我得到以下输出:

示例 LINQPad 输出

您甚至可以从您的问题中添加自己的代码:

string json = File.ReadAllText(@"d:\temp\test.json");
var genericObject = JsonConvert.DeserializeObject<Response>(json);

string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
  string errorField = errorElement.Key;
  string errorDescription = errorElement.Value.FirstOrDefault(); // see below
}

注意 1:迭代字典的结果是 a KeyValuePair<TKey, TValue>,在这种情况下它将是 a KeyValuePair<string, List<string>>

注意 2:您已经展示了 JSON 的每个字段都有一个数组,因此errorElement.errorMessage可能无法正常工作,因为您可能有多个错误消息。

但是,您可以嵌套一些循环来处理它们:

string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
  string errorField = errorElement.Key;
  foreach (string errorDescription in errorElement.Value)
  {
    // process errorField + errorDescription here
  }
}

推荐阅读