我正在尝试从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发送的相同的结构。答案是不会,因为你要跳过一层。所以最好是为"数据"创建。这样还可以维护层次结构,并且序列化和反序列化将是安全的。