으로는, 코멘트에 라세 칼슨에 의해 지적되었다, 그 클래스의 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
으로 변환 한 다음 JObject
을 JsonWriter
에 쓰기 전에 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"
}
}
}
생성자 인수로 해당 정보를 전달할 수 있습니까? –
예제에서 SharedClass가 문자열입니까? 매우 혼란 스럽습니다 ... – DrKoch
속성을 직렬화 할 때 JSON.NET을 중지시키는 데 사용할 수있는 속성이 없습니까? 어쩌면''비 직렬화 (NonSerialized) '가 작동 할 수도 있습니다. – Dirk