Json.NET (JsonConvert.DeserializeObject)



我正在尝试从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来表示图片下的数据对象。但理想情况下,我不希望另一个DTO只是为数据,并有JSON反序列化知道它可以找到图片DTO数据在图片。Data !

这是可能的,如果是,请怎么做?

非常感谢!

致以亲切的问候,nick

您可以使用自定义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();
    }
}

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

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

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

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

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

没有办法直接映射数据中的对象。或者,您可以从DTO创建一个测试对象,并使用JsonConvert对其进行序列化。看看它是否生成与FB发送的相同的结构。答案是不会,因为你要跳过一层。所以最好是为"数据"创建。这样还可以维护层次结构,并且序列化和反序列化将是安全的。

相关内容

  • 没有找到相关文章