2015-01-07 2 views
1

Newtonsoft.JSON 라이브러리를 사용하여 여러 개체를 직렬화합니다. 어떤 경우에는 속성을 serialize하지 않으므로 ShouldSerialize 접두사를 사용하여 대부분의 경우에 성공적으로 수행되었습니다. 특정 클래스에 속한 경우에만 속성을 serialize하려는 경우가 있습니다.상위 클래스 형식을 기반으로 직렬화에서 속성을 선택적으로 제외하는 방법

스택 추적을 사용해 보았지만 JSON 개체가 ShouldSerialize 메서드를 호출하고 있다고 알려주고 있습니다. ShouldSerialize를 호출 할 필요가 없습니다. 부모 클래스 ShouldSerialize가 Parent.Child.ShouldSerialize와 같은 것이 무엇인지 알아야합니다.

아래 코드 샘플을 사용하여 JSON 개체를 사용하는 동안 부모 클래스 이름을 어떻게 확인할 수 있습니까? 당신의 SharedClass 부모에 대한 참조를 가지고 있지 않은 경우

class Foo 
{ 
    public SharedClass SomeProperty 
    { 
      get; 
      set; 
    } 
} 

class Bar 
{ 
    public SharedClass SomeProperty 
    { 
      get; 
      set; 
    } 
} 

class SharedClass 
{ 
    public string SomeValue 
    { 
      get; 
      set; 
    } 

    public bool ShouldSerializeSomeValue 
    { 
      //pseudo logic 
      return ClassName == "Foo"; 
    } 
} 
+0

생성자 인수로 해당 정보를 전달할 수 있습니까? –

+2

예제에서 SharedClass가 문자열입니까? 매우 혼란 스럽습니다 ... – DrKoch

+0

속성을 직렬화 할 때 JSON.NET을 중지시키는 데 사용할 수있는 속성이 없습니까? 어쩌면''비 직렬화 (NonSerialized) '가 작동 할 수도 있습니다. – Dirk

답변

1

으로는, 코멘트에 라세 칼슨에 의해 지적되었다, 그 클래스의 ShouldSerializeSomeValue() 방법은 부모 클래스가 무엇인지 알 수있는 방법이 없습니다. 그러나

, 당신은 Json.Net 6.0 Release 6 이상을 사용하는 경우, 당신은 선택적으로 공유 클래스의 속성을 생략하는 수단으로 정의 JsonConverter를 사용하여 (대신 ShouldSerialize() 방법을 사용)에 의해이 문제를 해결 한 다음에 [JsonConverter] 특성을 배치 할 수 있습니다 적절한 부모 클래스에 속하는 SharedClass 속성을 사용하여 해당 인스턴스에 대해 어떤 속성을 생략해야하는지 나타냅니다.

다음은 업데이트 된 예제 클래스 정의의 모습입니다. SharedClass 인스턴스를 Foo에 표시하면 OmitPropertiesConverter이라는 사용자 지정 변환기를 사용하여 SomeValue 속성을 생략해야한다는 것을 알 수 있습니다. SharedClass 인스턴스가 Bar이면 변환기가 사용되지 않으므로 인스턴스는 정상적으로 직렬화됩니다.

class Foo 
{ 
    [JsonConverter(typeof(OmitPropertiesConverter), "SomeValue")] 
    public SharedClass Shared { get; set; } 
} 

class Bar 
{ 
    public SharedClass Shared { get; set; } 
} 

class SharedClass 
{ 
    public string SomeValue { get; set; } 
    public string SomeOtherValue { get; set; } 
} 

다음은 OmitPropertiesConverter의 코드입니다. 생성자는 propsToOmit 문자열을 수락합니다.이 문자열은 직렬화에서 제외 할 속성 이름의 쉼표로 구분 된 목록입니다. 이것은 나중에 WriteJson 메소드에서 사용하기 위해 배열로 분할됩니다. WriteJson 메서드는 SharedClass 값을 사용하여 JObject으로 변환 한 다음 JObjectJsonWriter에 쓰기 전에 propsToOmit 배열에있는 속성을 프로그래밍 방식으로 제거합니다. 여기

class Program 
{ 
    static void Main(string[] args) 
    { 
     var root = new 
     { 
      Foo = new Foo 
      { 
       Shared = new SharedClass 
       { 
        SomeValue = "foo1", 
        SomeOtherValue = "foo2" 
       } 
      }, 
      Bar = new Bar 
      { 
       Shared = new SharedClass 
       { 
        SomeValue = "bar1", 
        SomeOtherValue = "bar2" 
       } 
      } 
     }; 

     string json = JsonConvert.SerializeObject(root, Formatting.Indented); 
     Console.WriteLine(json); 
    } 
} 

하고, 상기 데모의 출력은 :

class OmitPropertiesConverter : JsonConverter 
{ 
    string[] propsToOmit; 

    public OmitPropertiesConverter(string propsToOmit) 
    { 
     this.propsToOmit = propsToOmit.Split(new char[] {','}, 
              StringSplitOptions.RemoveEmptyEntries); 
    } 

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

    public override void WriteJson(JsonWriter writer, object value, 
            JsonSerializer serializer) 
    { 
     JObject jo = JObject.FromObject(value, serializer); 

     // Note: ToList() is needed here to prevent "collection was modified" error 
     foreach (JProperty prop in jo.Properties() 
            .Where(p => propsToOmit.Contains(p.Name)) 
            .ToList()) 
     { 
      prop.Remove(); 
     } 

     jo.WriteTo(writer); 
    } 

    public override bool CanRead 
    { 
     get { return false; } 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

찾는 작업에서 변환기를 보여주는 간단한 데모 프로그램이다. SharedClass 내부의 SomeValue 속성은 출력에 포함되어 있지 않지만 Bar 내부의 인스턴스에 포함되어 있습니다.

{ 
    "Foo": { 
    "Shared": { 
     "SomeOtherValue": "foo2" 
    } 
    }, 
    "Bar": { 
    "Shared": { 
     "SomeValue": "bar1", 
     "SomeOtherValue": "bar2" 
    } 
    } 
} 
+0

그래, 그게 내가 원하는거야. 불행히도 Newtonsoft.Json 라이브러리를 사용하는 것으로 제한됩니다. – blkbam

+0

Json.Net과 Newtonsoft.Json은 동일한 라이브러리입니다. 따라서 이미이 라이브러리를 사용하고 있다면이 솔루션을 사용할 수 있어야합니다. 시도 해봐. –

+0

지연에 대해 유감스럽게 생각하는 다른 작업을해야했습니다. 처음에는 Json.Net에서 OmitPropertiesConverter의 샘플 구성을 보여 주긴했지만. 독서를 통해 나는 그것을 지금 얻는다. 나는 당신에게 코드를 시도했고 그것은 내가 필요한 것을 정확히한다. 감사! – blkbam

관련 문제