【问题标题】:Facing issues deserializing JSON into .NET面临将 JSON 反序列化为 .NET 的问题
【发布时间】:2015-02-21 09:01:34
【问题描述】:

我对处理 JSON 比较陌生。但是已经成功地创建了一些返回我想要的类的类。然而,这个反应让我很困惑。

我已经查看并尝试了网站上的各种示例,以将我的 JSON 响应转换为一个类。但是,我继续遇到运行时错误。 任何关于我哪里出错的指示将不胜感激。

JSON 响应

{
    "locationResponse": {
        "locations": [
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:Jonathon Doe,state:WA,houseNum:23619",
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:Jon Doe,state:WA,houseNum:23619",
            "ad1c:2dbf:fadf:2e87",
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:John Doe,state:WA,houseNum:23619",
            "E911AID:93a6:2db4:0589:261d,streetDir:NE,street:89th,zip:98052,city:Redmond,streetNameSuffix:St,name:JJ Doe,state:WA,houseNum:23619"
        ]
    }
}

类定义

[Serializable]
public class locationResponseResponse
{
    public locationResponse locationResponse { get; set; }
}
[Serializable]
public class locationResponse
{
    public location[] locations { get; set; }
}
[Serializable]
public class location
{
    public string E911AID { get; set; }
    public string streetDir { get; set; }
    public string street { get; set; }
    public string zip { get; set; }
    public string city { get; set; }
    public string streetNameSuffix { get; set; }
    public string name { get; set; }
    public string state { get; set; }
    public string houseNumber { get; set; }
}

反序列化代码段

public locationResponseResponse GetlocationResponseResponse(string jsonString)
{
    locationResponseResponse _response = new locationResponseResponse();
    if (!string.IsNullOrEmpty(jsonString))
    {
        JavaScriptSerializer ser = new JavaScriptSerializer();
        _response = ser.Deserialize<locationResponseResponse>(jsonString);
    }
    return _response;
}

收到运行时错误

没有为BlackFlagAPI.locationResponse[] 类型定义无参数构造函数。

【问题讨论】:

  • 考虑使用 Newtsoft.Json。它是最流行的 json 序列化器。
  • json 示例中的 locations 是字符串,而不是 json 对象。所以一个 json 反序列化器不能把它们变成你的 location 类。您需要为此注册一个自定义解析器。
  • 下次发 json 时,请使用漂亮打印的 json。更容易看到正在发生的事情。
  • 我修复了你的 JSON,这个工作正常:gist.github.com/cubrr/ac9b70961301193caf49

标签: c# .net json serialization javascriptserializer


【解决方案1】:

json 示例中的 locations 是字符串,而不是 json 对象。所以一个 json 反序列化器不能把它们变成你的 location 类。字符串内容也不是序列化的 json 文档。

您需要为此注册一个自定义解析器,但由于我从未使用过 JavascriptSerializer,因此我无法告诉您如何操作。

或者,如果您可以控制 json 的来源,请使用 json 对位置数据进行编码,而不是在字符串中嵌入自定义格式。

【讨论】:

    【解决方案2】:

    对于您发布的 JSON,该类类似于以下内容:

    public class LocationResponse
    {
        public List<string> locations { get; set; }
    }
    
    public class Root
    {
         public LocationResponse locationResponse { get; set; }
    }
    

    然后您需要手动解析位置。否则,您需要更正 JSON 结构。

    【讨论】:

      【解决方案3】:

      Locations 在您的 json 中不是 json 对象。它们是name:value 形式的字符串,由, 分隔。

      所以需要分两步解析

      1- 反序列化 json

      var root = new JavaScriptSerializer().Deserialize<RootObject>(json);
      

      2- 解析每个字符串

      var addrs = root.locationResponse.locations
                      .Select(x => x.Split(','))
                      .Select(parts =>
                      {
                          var l = new Location();
                          var props = l.GetType().GetProperties();
                          foreach (var part in parts)
                          {
                              var kv = part.Split(new char[] { ':' }, 2);
                              var prop = l.GetType().GetProperty(kv[0]);
                              if(prop != null)
                                  prop.SetValue(l, kv[1]);
      
                          }
                          return l;
                      })
                      .ToList();
      

      public class Location
      {
          public string E911AID { get; set; }
          public string streetDir { get; set; }
          public string street { get; set; }
          public string zip { get; set; }
          public string city { get; set; }
          public string streetNameSuffix { get; set; }
          public string name { get; set; }
          public string state { get; set; }
          public string houseNum { get; set; }
      }
      
      public class LocationResponse
      {
          public List<string> locations { get; set; }
      }
      
      public class RootObject
      {
          public LocationResponse locationResponse { get; set; }
      }
      

      【讨论】:

      • 谢谢,经过深入挖掘,我收到 JSON 响应的服务似乎存在错误。我没有注意到只包含一个 ID 的近乎空的行。这似乎是问题的症结所在。一旦我放弃了这条坏线,即使我的原始代码也可以工作。现在我需要确定 JSON 输出是否有缺陷,并可能修复内联或简单地出错。非常感谢所有的帮助。
      猜你喜欢
      • 1970-01-01
      • 2016-06-17
      • 2014-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多