JSON.Net - Изменить поле $type на другое имя?

При использовании Json.Net я понимаю, как получить свойство $type в отображаемом json, но есть ли способ изменить имя этого поля? Мне нужно использовать "__type" вместо "$type".

25
задан Brian McCord 28 February 2012 в 21:54
поделиться

2 ответа

Мы нуждались в этом, поэтому я создал собственный 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);
    }
}
4
ответ дан 28 November 2019 в 20:46
поделиться

Вы также можете сделать это следующим образом:

[JsonConverter(typeof(JsonSubtypes), "ClassName")]
public class Annimal
{
    public virtual string ClassName { get; }
    public string Color { get; set; }
}

Вам понадобится конвертер JsonSubtypes , который не является частью проекта Newtonsoft.Json.

2
ответ дан 28 November 2019 в 20:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: