Json.NET(JsonConvert.DeserializeObject)

时间:2016-10-06 04:20:01

标签: .net json json.net deserialization

我正在尝试从facebook / me反序列化以下JSON响应。

{
   "id": "53234...",
   "first_name": "Nik",
   "last_name": "Westfield",
   "email": "nik@youremail.com",
   "picture": {
      "data": {
         "height": 720,
         "is_silhouette": false,
         "url": "https://scontent.xx.fbcdn.net/v/t1.0-1/p720x720/3221.....",
         "width": 720
      }
   }
}

如何在不创建其他DTO的情况下获取图片/数据属性?

var me = await Task.Run(() => JsonConvert.DeserializeObject<FacebookMeDto>(json)).ConfigureAwait(false);

的DTO:

public class FacebookMeDto
    {
        [JsonProperty("id")]
        public string Id { get; set; }

        ...

        [JsonProperty("picture")]
        public FacebookPictureDto PictureDto { get; set; }
    }

public class FacebookPictureDto
    {
        [JsonProperty("height")]
        public int Height { get; set; }

        ...

        [JsonProperty("url")]
        public string Url { get; set; }
    }

不幸的是,它上面的代码没有工作,因为我错过了额外的DTO来表示图片下的Data对象。但理想情况下,我不想仅仅为Data提供另一个DTO,并且让JSON反序列化知道它可以在picture.data下找到picture-DTO数据!

这可能吗?如果可以的话,请问怎么样?

非常感谢!

亲切的问候,Nik

3 个答案:

答案 0 :(得分:1)

如果您使用Facebook登录,我建议您使用Visual Studio在默认项目中为您生成的ASP.NET Identity Facebook提供程序。

话虽如此,解决问题的更好方法是使用DTO。它可以保证您的代码类型安全。另一种方法是将对象反序列化为Dynamic对象。您可以在这个很棒的答案中找到进一步的帮助:Deserialize JSON into C# dynamic object?

答案 1 :(得分:1)

无法直接在数据中映射对象。或者,您可以从DTO创建测试对象并使用JsonConvert对其进行序列化。查看它是否生成与FB发送的结构相同的结构。答案是不会,因为你试图跳过一层。因此,如果您为“数据”正确创建,那就更好了。这种方式层次结构也得到维护,序列化和反序列化将是安全的。

答案 2 :(得分:1)

您可以使用自定义JsonConverter弥补差距,这样您就不必在模型上创建中间DTO。以下是转换器所需的代码:

public class FacebookPictureDtoConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(FacebookPictureDto);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);
        FacebookPictureDto dto = new FacebookPictureDto();
        serializer.Populate(obj["data"].CreateReader(), dto);
        return dto;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用转换器,请在[JsonConverter]属性中添加PictureDto属性,如下所示:

public class FacebookMeDto
{
    [JsonProperty("picture")]
    [JsonConverter(typeof(FacebookPictureDtoConverter))]
    public FacebookPictureDto PictureDto { get; set; }
}

小提琴:https://dotnetfiddle.net/Tx9FS9