2014-12-13 3 views
3

JSON.Net을 사용하여 비 직렬화 된 모델 클래스 Link이 있습니다. DefaultImageUri, SmallImageUri, MediumImageUri :Json.NET - 클래스 객체 속성 비 직렬화 제어

public class Link 
{ 
    [JsonConstructor] 
    internal Link(int id) 
    { 
     Id = id; 
    } 

    public int Id { get; internal set; } 

    [JsonProperty("title")] 
    public string Title { get; internal set; } 

    [JsonProperty("description")] 
    public string Description { get; internal set; } 

... and so on 

    public Avatar AuthorAvatar { get; internal set; } 
} 

아바타 세 가지 속성이 포함되어 있습니다. 객체 비 직렬화에서 Avatar 객체를 만들 수 있습니까? author_avatar, author_avatar_small, author_avatar_medium json fields?

+0

내가 난 그냥 세 "JsonProperty"에서 만들 수 AuthorAvatar 원하는 질문 ... t3chb0t @ – t3chb0t

+0

이해가 안 무서워 - author_avatar을 author_avatar_small, author_avatar_medium 링크 클래스에 Uri AuthorAvatarDefault, Uri AuthorAvatarSmall, Uri AuthorAvatarMedium이라는 세 개의 Uri 필드가있는 대신 (아바타라는 다른 클래스에 '포장'하고 싶음) – fex

답변

3

난 당신이 여기에 예를 JsonConverter 자신입니다 작성하여이를 수 있다고 믿는다 (I 직렬화 부분을 생략하지만, 구현은 매우 유사하다 드 직렬화) :

샘플 :

class Program 
{ 
    private static void Main(string[] args) 
    { 
     var json = @"{ 
         id:1, 
         title: 'link title', 
         description: 'link description', 
         author_avatar:'link', 
         author_avatar_small:'small link', 
         author_avatar_medium:'medium link', 
        }"; 

     var obj = JsonConvert.DeserializeObject<Link>(json); 
    } 
} 

클래스 정의 :

[JsonConverter(typeof(LinkSerializer))] 
public class Link 
{ 
    [JsonConstructor] 
    public Link(int id) 
    { 
     Id = id; 
    } 

    [JsonIgnore] 
    public int Id { get; internal set; } 

    [JsonProperty("title")] 
    public string Title { get; internal set; } 

    [JsonProperty("description")] 
    public string Description { get; internal set; } 


    public Avatar AuthorAvatar { get; internal set; } 
} 

public class Avatar 
{ 
    [JsonProperty("author_avatar")] 
    public string DefaultImageUri { get; internal set; } 
    [JsonProperty("author_avatar_small")] 
    public string SmallImageUri { get; internal set; } 
    [JsonProperty("author_avatar_medium")] 
    public string MediumImageUri { get; internal set; } 
} 

사용자 정의 링크 시리얼 :

public class LinkSerializer : JsonConverter 
{ 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof (Link) == objectType; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var jObject = JObject.Load(reader); 

     //NOTE:I changed .ctor to publec to simplify the process, we can also check for JsonConstructor attribute on constructors and the call appropriate one 
     var value = existingValue ?? Activator.CreateInstance(objectType, jObject["id"].Value<int>()); 
     Populate(objectType, jObject, value); 

     var avatar = Activator.CreateInstance<Avatar>(); //Fill avatar object 
     Populate(avatar.GetType(),jObject,avatar); 

     objectType.GetProperty("AuthorAvatar").SetValue(value,avatar); //set avatar object 

     return value; 
    } 

    private static void Populate(Type objectType, JObject jObject, object value) 
    { 
     var properties = 
      objectType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 

     foreach (var p in properties) 
     { 
      var ignore = p.GetCustomAttribute<JsonIgnoreAttribute>(); 
      if (ignore != null) 
       continue; 

      var custom = p.GetCustomAttribute<JsonPropertyAttribute>(); 
      var name = custom != null ? custom.PropertyName : p.Name; 

      var token = jObject[name]; 
      var obj = token != null 
       ? token.ToObject(p.PropertyType) 
       : p.PropertyType.IsValueType ? Activator.CreateInstance(p.PropertyType) : null; 

      p.SetValue(value, obj); 
     } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     //we just want to deserialize the object so we don't need it here, but the implementation would be very similar to deserialization 
    } 
2

다음과 같은 것이 있습니까?

class Program 
{ 
    static void Main(string[] args) 
    { 

     string json = 
     @"{ 
      Id: 1, 
      author_avatar: 'abc', 
      author_avatar_small: 'small', 
      author_avatar_medium: 'medium' 
     }"; 
     var link = JsonConvert.DeserializeObject<Link>(json); 
    } 
} 

public class Link 
{ 
    public Link(string author_avatar, string author_avatar_small, string author_avatar_medium) 
    { 
     AuthorAvatar = new Avatar(author_avatar, author_avatar_small, author_avatar_medium); 
    } 
    public int Id { get; set; } 
    public Avatar AuthorAvatar { get; set; } 
} 

public class Avatar 
{ 
    public Avatar(string author_avatar, string author_avatar_small, string author_avatar_medium) 
    { 
     DefaultImageUri = author_avatar; 
     SmallImageUri = author_avatar_small; 
     MediumImageUri = author_avatar_medium; 
    } 
    public string DefaultImageUri { get; set; } 
    public string SmallImageUri { get; set; } 
    public string MediumImageUri { get; set; } 
} 
관련 문제