【问题标题】:Serialize deserialize anonymous child JSON properties to model序列化反序列化匿名子 JSON 属性以建模
【发布时间】:2013-08-14 13:24:50
【问题描述】:

我有一个从中接收数据的 API。该 API 无法控制它的结构,我需要序列化和反序列化 JSON 输出以将数据映射到我的模型。

如果 JSON 具有良好的命名属性格式,则一切正常。

如果没有命名值而只有一个整数和字符串数组,你能做什么?比如在位置

这是 JSON 的示例:

{"id":"2160336","activation_date":"2013-08-01","expiration_date":"2013-08-29","title":"Practice Manager","locations":{"103":"Cambridge","107":"London"}}

我有类似的模型:

public class ItemResults
{
    public int Id { get; set; }

    public DateTime Activation_Date { get; set; }

    public DateTime Expiration_Date{ get; set; } 

    public string Title { get; set; }

    public Location Locations { get; set; }
}

public class Location
{
    public int Id { get; set; }

    public string value { get; set; }
}

我正在使用内置的 ajax 序列化进行映射:

 protected T MapRawApiResponseTo<T>( string response )
    {
        if ( string.IsNullOrEmpty( response ) )
        {
            return default( T );
        }

        var serialize = new JavaScriptSerializer();

        return serialize.Deserialize<T>( response );
    }

var results = MapRawApiResponseTo<ItemResults>(rawApiResponse);

因此,ID 和所有其他属性都被拾取并映射,但我所做的每一件事似乎都无法映射位置。

非常感谢

【问题讨论】:

  • ItemResults 类中的字段不应该是一个集合并命名为复数吗?例如public IEnumerable&lt;Location&gt; Locations { get; set; }
  • 与许多涉及JavaScriptSerializer的JSON问题一样,任何答案的第一部分通常应该是“停止使用JavaScriptSerializer”;抱歉,但对于任何不重要的事情,Json.NET 做得好多 更好
  • 删除了我的答案,因为格式不好,但这是一个有用的网站,可以查看如何构建您的课程:json2csharp.com

标签: c# serialization deserialization


【解决方案1】:
public Dictionary<int,string> Locations { get; set; }

工作完成;你应该发现至少使用 Json.NET,即

var result = JsonConvert.DeserializeObject<ItemResults>(json);

result.Locations 中有 2 个条目;特别是result[103] = "Cambridge";result[107] = "London";

【讨论】:

  • 对我的问题的简单解决方案非常棒,非常感谢您的所有回复
【解决方案2】:

如果你不介意,你可以用字典解决:

class Program
{
    static void Main(string[] args)
    {
        string json =
            "{'id':'2160336','activation_date':'2013-08-01','expiration_date':'2013-08-29','title':'Practice Manager','locations':{'103':'Cambridge','107':'London'}}";
        var deserializeObject = JsonConvert.DeserializeObject<ItemResults>(json);
        Console.WriteLine("{0}:{1}", deserializeObject.Locations.First().Key, deserializeObject.Locations.First().Value);
        Console.ReadKey();
    }
}

public class ItemResults
{
    public int Id { get; set; }
    public DateTime Activation_Date { get; set; }
    public DateTime Expiration_Date { get; set; }
    public string Title { get; set; }
    public Dictionary<int, string> Locations { get; set; }
}

你也可以使用手动解析,比如这里:Json.NET (Newtonsoft.Json) - Two 'properties' with same name?

【讨论】:

    【解决方案3】:

    这将起作用:

    public Dictionary<string, string> Locations { get; set; }
    
    public IEnumerable<Location> LocationObjects { get { return Locations
         .Select(x => new Location { Id = int.Parse(x.Key), value = x.Value }); } }
    

    【讨论】:

      【解决方案4】:

      我建议你以下解决方案:

      public class ItemResults
      {
          public int Id { get; set; }
      
          public DateTime Activation_Date { get; set; }
      
          public DateTime Expiration_Date { get; set; }
      
          public string Title { get; set; }
      
          [JsonProperty("locations")]
          public JObject JsonLocations { get; set; }
      
          [JsonIgnore]
          public List<Location> Locations { get; set; }
      
          [OnDeserialized]
          public void OnDeserializedMethod(StreamingContext context)
          {
              this.Locations = new List<Location>();
              foreach (KeyValuePair<string, JToken> item in this.JsonLocations)
              {
                  this.Locations.Add(new Location() { Id = int.Parse(item.Key), value = item.Value.ToString() });
              }
          }
      }
      
      public class Location
      {
          public int Id { get; set; }
      
          public string value { get; set; }
      }
      

      在你只需要反序列化你的 JSON 之后:JsonConvert.DeserializeObject&lt;ItemResults&gt;(json);

      【讨论】:

      • 与只使用Dictionary&lt;int,string&gt; 相比,这样做有点困难,只是有点......?
      • 如果一个位置只是一个带有值的 id,那么是的,这很难。但如果有更多属性(地理位置、完整地址等),这种方式可能会有所帮助:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      相关资源
      最近更新 更多