将动态json反序列化为通用.NET对象

时间:2019-07-31 16:13:31

标签: c# .net json 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:

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

4 个答案:

答案 0 :(得分:2)

由于您提到自己不知道会出现哪些“错误字段”,因此词典是最好的选择。

这是一个简单的例子:

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中执行此操作时,得到以下输出:

sample LINQPad output

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

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::迭代字典的结果是KeyValuePair<TKey, TValue>,在这种情况下,它是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
  }
}

答案 1 :(得分:1)

有很多方法可以做到这一点。

System.Web.Helpers程序集包含您可以执行的Json类:

dynamic decodedObject = Json.Decode(json);

另一种方法是使用Newtonsoft.Json nuget包:

var deserializedObject = JsonConvert.DeserializeObject<dynamic>(json);

答案 2 :(得分:1)

如果您愿意使用Newtonsoft.Json,则可以使用:

var json = JsonConvert.DeserializeObject<dynamic>(originalJson);

答案 3 :(得分:0)

您将必须创建以下类:
RootObject.cs包含以下属性:

public class RootObject
{
    [JsonProperty("message")]
    public string Message { get; set; }

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

Errors.cs,包含以下属性:

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

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

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

然后您阅读了整个内容:

var inputObj = JsonConvert.DeserializeObject<RootObject>(json);

inputObj的类型为RootObject,而json是您接收的JSON。

如果您已正确实现此功能,请按以下方式使用它:

var message = inputObj.Message;
var nameErrors = inputObj.Errors;
var firstNameError = inputObj.Errors.Name[0];

以下是视觉效果: 显示整个对象,并填充以下属性: enter image description here

“主要”错误: enter image description here

如有任何疑问,请随时提问。