Json.Net은 동적 유형에 대해서만 형식 이름 처리를 해제하는 특정 설정을 제공하지 않습니다. 관련 동적 속성을 [JsonProperty(TypeNameHandling = TypeNameHandling.None)]
으로 표시 할 수 없다면 (또는 Json.Net 소스 코드 자체를 수정하지 않은 경우) 사용자 지정 계약 해결자를 구현하여 프로그래밍 방식으로 동작을 적용 할 수 있습니다 . 하지만 걱정하지 마세요. DefaultContractResolver
또는 CamelCasePropertyNamesContractResolver
과 같은 Json.Net 제공 해결 프로그램 중 하나에서 해결자를 파생 시키면 어렵지 않습니다.
using System;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class OmitTypeNamesOnDynamicsResolver : DefaultContractResolver
{
public static readonly OmitTypeNamesOnDynamicsResolver Instance = new OmitTypeNamesOnDynamicsResolver();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (member.GetCustomAttribute<System.Runtime.CompilerServices.DynamicAttribute>() != null)
{
prop.TypeNameHandling = TypeNameHandling.None;
}
return prop;
}
}
그런 다음, 바로 JsonSerializerSettings
에 리졸버를 추가하고 모든 설정해야한다 : 여기
는 당신이 필요로하는 모든 코드입니다.
public class Program
{
public static void Main(string[] args)
{
Foo foo = new Foo
{
Model = new { link = "http://www.google.com", name = "John" },
Widget1 = new Doodad { Name = "Sprocket", Size = 10 },
Widget2 = new Thingy { Name = "Coil", Strength = 5 }
};
JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
ContractResolver = OmitTypeNamesOnDynamicsResolver.Instance,
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(foo, settings);
Console.WriteLine(json);
Console.WriteLine();
Foo foo2 = JsonConvert.DeserializeObject<Foo>(json, settings);
Console.WriteLine(foo2.Model.link);
Console.WriteLine(foo2.Model.name);
Console.WriteLine(foo2.Widget1.Name + " (" + foo2.Widget1.GetType().Name + ")");
Console.WriteLine(foo2.Widget2.Name + " (" + foo2.Widget2.GetType().Name + ")");
}
}
public class Foo
{
public dynamic Model { get; set; }
public AbstractWidget Widget1 { get; set; }
public AbstractWidget Widget2 { get; set; }
}
public class AbstractWidget
{
public string Name { get; set; }
}
public class Thingy : AbstractWidget
{
public int Strength { get; set; }
}
public class Doodad : AbstractWidget
{
public int Size { get; set; }
}
출력 :
{
"Model": {
"link": "http://www.google.com",
"name": "John"
},
"Widget1": {
"$type": "Doodad, JsonTest",
"Size": 10,
"Name": "Sprocket"
},
"Widget2": {
"$type": "Thingy, JsonTest",
"Strength": 5,
"Name": "Coil"
}
}
http://www.google.com
John
Sprocket (Doodad)
Coil (Thingy)
[JsonIgnore] 또는 조건부 직렬화 (http://www.newtonsoft.com 여기
의 개념을 증명하기 위해 왕복 데모 인 /json/help/html/conditionalproperties.htm) 유용 할 수도 있습니다. – Nair@Nair : 감사합니다.하지만 불행합니다.나는 도메인 객체를 소유하지 않으므로 속성이나 메소드로 장식 할 수 없다. 게다가, 그것은 모든 객체에 대해 이렇게해야하므로 잘 확장되지 않습니다. – pardahlman
관련 속성에'[JsonProperty (TypeNameHandling = TypeNameHandling.None)]'을 추가하는 것이 가장 간단한 방법 일 것입니다. 그러나 주석에서 당신은 그렇게 할 수 없다고 말합니다. 해당 요구 사항을 명확히하기 위해 질문을 편집 할 수 있습니다. – dbc