При использовании Json.Net я понимаю, как получить свойство $type в отображаемом json, но есть ли способ изменить имя этого поля? Мне нужно использовать "__type" вместо "$type".
Мы нуждались в этом, поэтому я создал собственный JsonReader. Мы используем rest в наших веб-службах MS со сложными моделями данных, и нам нужно заменить свойство «__type» на «$ type».
class MSJsonReader : JsonTextReader
{
public MSJsonTextReader(TextReader reader) : base(reader) { }
public override bool Read()
{
var hasToken = base.Read();
if (hasToken && base.TokenType == JsonToken.PropertyName && base.Value != null && base.Value.Equals("__type"))
base.SetToken(JsonToken.PropertyName, "$type");
return hasToken;
}
}
Вот как мы его используем.
using(JsonReader jr = new MSJsonTextReader(sr))
{
JsonSerializer s = new JsonSerializer();
s.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
s.NullValueHandling = NullValueHandling.Ignore;
s.TypeNameHandling = TypeNameHandling.Auto; // Important!
s.Binder = new MSRestToJsonDotNetSerializationBinder("Server.DataModelsNamespace", "Client.GeneratedModelsNamespace");
T deserialized = s.Deserialize<T>(jr);
return deserialized;
}
Вот наш MSRestToJsonDotNetSerializationBinder, который завершает совместимость между MS rest и Json.Net.
class MSRestToJsonDotNetSerializationBinder : System.Runtime.Serialization.SerializationBinder
{
public string ServiceNamespace { get; set; }
public string LocalNamespace { get; set; }
public MSRestToJsonDotNetSerializationBinder(string serviceNamespace, string localNamespace)
{
if (serviceNamespace.EndsWith("."))
serviceNamespace = serviceNamespace.Substring(0, -1);
if(localNamespace.EndsWith("."))
localNamespace = localNamespace.Substring(0, -1);
ServiceNamespace = serviceNamespace;
LocalNamespace = localNamespace;
}
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
assemblyName = null;
typeName = string.Format("{0}:#{1}", serializedType.Name, ServiceNamespace); // MS format
}
public override Type BindToType(string assemblyName, string typeName)
{
string jsonDotNetType = string.Format("{0}.{1}", LocalNamespace, typeName.Substring(0, typeName.IndexOf(":#")));
return Type.GetType(jsonDotNetType);
}
}
Вы также можете сделать это следующим образом:
[JsonConverter(typeof(JsonSubtypes), "ClassName")]
public class Annimal
{
public virtual string ClassName { get; }
public string Color { get; set; }
}
Вам понадобится конвертер JsonSubtypes
, который не является частью проекта Newtonsoft.Json
.