【问题标题】:In C# how can I deserialize this json when one field might be a string or an array of strings?在 C# 中,当一个字段可能是字符串或字符串数​​组时,如何反序列化此 json?
【发布时间】:2012-04-13 13:20:26
【问题描述】:

我有一个 asp.net-mvc 网站,我正在从数据库中读取 Json 字符串。这是数据库中的以下 json。它可能看起来像这样:

{"description": "Test", "contacts": ["joe@gmail.com", "bill@yahoo.com"], "enabled": true}

或者这个:

{"description": "Test", "contacts": "joe@gmail.com, bill@yahoo.com", "enabled": true}

如您所见,联系人字段是:

  1. 一个字符串(项目用逗号分隔)
  2. 字符串数组。

我想转成这个类:

public class MyJob
{
    public string description;
    public string[] contacts;
    public string enabled;
}

当我尝试仅分配给一个字符串时(将上面的内容更改为:公共字符串联系人; ) 使用 JavascriptSerializer():

var serializer = new JavaScriptSerializer();
string contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;

在数组的情况下出现此错误:Type 'System.String' is not supported for deserialization of an array.

反序列化处理以下情况的最佳方法是什么:

  1. 一个字符串
  2. 字符串数组。

用于联系人字段。我很乐意提出任何需要的条件逻辑。 .

我试过了:

  var contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;
        if (contacts is string)
        {
            jobInfo.contacts = contacts;
        }
        else
        {
            jobInfo.contacts = String.Join("; ", contacts );
        }

但这似乎没有解决,因为当它是一个数组时我仍然收到上面的错误

【问题讨论】:

  • 我不认为您可以编写脚本以在数据库中以一致的方式对这些值进行编码?
  • 不幸的是没有。我不拥有数据库或数据

标签: c# json deserialization javascriptserializer


【解决方案1】:

试试

  var contacts = (new JavaScriptSerializer().DeserializeObject(theAboveJsonString) as Dictionary<string, object>)["contacts"];

  if (contacts is object[])
  {
      jobInfo.contacts = String.Join("; ", contacts as object[]);
  }
  else
  {
      jobInfo.contacts = contacts.ToString(); 
  }

有关参考,请参阅 MSDNhere

【讨论】:

    【解决方案2】:

    您可能对这里的一些细节感兴趣:JSON.net - field is either string or List<string>

    如果你愿意使用Json.NET,有这个功能:

    public string[] getAsArray(JToken token)
    {
        if (token.HasValues)
        {
            return token.Select(m => string(m)).ToArray();
        }
        else
        {
            return ((string)token).Split(",").Select(s => s.Trim()).ToArray();
        }
    }
    

    然后用法:

    var json = "...";
    JObject o = JObject.Parse(json);
    string[] contacts = getAsArray(o["contacts"]);
    

    对于任一 JSON,结果应该相同。

    【讨论】:

      【解决方案3】:

      尝试将联系人反序列化为字符串数组而不是普通字符串:

      string[] contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;
      

      如果 JSON 变量包含纯字符串,请使用:

      string[] contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts.Split(',');
      

      【讨论】:

      • 根据问题,它可能是一个字符串,也可能是一个数组。 .
      • 如果该字段包含一个字符串,则使用 contacts.Split(',') 将其转换为数组。无论哪种方式,您都需要将其分配给字符串数组而不是普通字符串变量。
      • 马特 - 我认为你错过了问题的重点。 .问题是该字段可以是任何一种数据类型。 .问题的重点是我如何处理这种情况
      • 对不起。处理此问题的最佳方法是将其一致地输入数据库。如果你不能这样做,那么首先测试它是一个数组,如果它不是一个数组,那么使用 string.Split(',')。要测试数组,请使用 contacts.GetType().IsArray;
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多