我正在尝试从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
答案 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; }
}