2016-10-06 1 views
0

私はfacebook/meから次のJSON応答をデシリアライズしようとしています。Json.NET(JsonConvert.DeserializeObject)

{ 
    "id": "53234...", 
    "first_name": "Nik", 
    "last_name": "Westfield", 
    "email": "[email protected]", 
    "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:私は絵の下にデータオブジェクトを表すために、余分な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; } 
    } 

は残念ながら上記のコードは動作しません。しかし理想的には、私はDataだけのために別のDTOを望んでいないし、JSON deserialiseにpicture.dataの下でpicture-DTOデータを見つけることができることを知ってもらいたい!

これは可能ですか?あればどうですか?

ありがとうございます!

敬具、ニック

答えて

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(); 
    } 
} 

コンバータを使用するには、このようなPictureDtoプロパティに[JsonConverter]属性を追加します:ここでは、コンバータのために必要となるコードがある

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

フィドル:https://dotnetfiddle.net/Tx9FS9

+0

グレート答え!どうもありがとうございました!これはまさに私が後にしたものです! – Nik

+0

問題ありません。お役に立てて嬉しいです。 –

1

あなたはFacebookのログインを使用している場合、私はあなたがVisual Studioがデフォルトのプロジェクトであなたのために生成ASP.NETアイデンティティFacebookのプロバイダを使用することを推奨します。

あなたの問題を解決するより良いアプローチは、DTOを使用することです。コードタイプを安全に保ちます。もう1つの方法は、オブジェクトを動的オブジェクトに逆直列化することです。あなたはこの偉大な答えでさらに助けを見つけることができます:Deserialize JSON into C# dynamic object?

1

データにオブジェクトを直接マップする方法はありません。また、DTOからテストオブジェクトを作成し、JsonConvertを使用してシリアル化することもできます。 FBによって送信されたのと同じ構造を生成するかどうかを確認してください。あなたは1つのレイヤーをスキップしようとしているので、答えはありません。したがって、「データ」に対して適切に作成する方がよいでしょう。このようにして階層も維持され、シリアライゼーションとデシリアライゼーションは安全です。