JSON.Net - 将$ type字段更改为其他名称?

Bri*_*ord 25 json.net

当使用Json.Net时,我理解如何将$ type属性放入渲染的json中,但有没有办法更改该字段名称?我需要使用"__type"而不是"$ type".

dri*_*kin 17

看起来这是硬编码public const string TypePropertyName = "$type";Newtonsoft.Json.Serialization.JsonTypeReflector其中是内部静态类很遗憾.

我自己需要这个,我唯一能想到的就是拥有json.net自定义修改版本.这当然是一个主要的皮塔饼.

  • 不幸的是,由于Json.Net在许多情况下的使用有多么困难,我几乎不得不完全放弃我的目标.这只是一个例子. (4认同)

Ian*_*ton 16

http://json.codeplex.com/workitem/22429

"我宁愿保持$ type硬编码和一致."

与我想知道的一致?

http://json.codeplex.com/workitem/21989

我宁愿不 - 我认为这对我来说太具体了,我不想过度设置.在某些时候,我可能会实现这个 - http://json.codeplex.com/workitem/21856 - 允许人们在JSON中读/写自己的元属性,你可以用新的属性名重新实现类型名称处理.另一种选择就是修改自己的源代码以获得该属性名称.

这是我的解决方案......

json.Replace("\"$type\": \"", "\"type\": \"");
Run Code Online (Sandbox Code Playgroud)


Lie*_*ero 6

序列化时,有一种很好的方法可以覆盖属性名称:

public class CustomJsonWriter : JsonTextWriter
{
    public CustomJsonWriter(TextWriter writer) : base(writer)
    {
    }

    public override void WritePropertyName(string name, bool escape)
    {
        if (name == "$type") name = "__type";
        base.WritePropertyName(name, escape);
    }
}

var serializer = new JsonSerializer();
var writer = new StreamWriter(stream) { AutoFlush = true };
serializer.Serialize(new CustomJsonWriter(writer), objectToSerialize);
Run Code Online (Sandbox Code Playgroud)

我还没有尝试过反序列化,但是在最坏的情况下,我可以使用:

json.Replace("\"__type": \"", "\"type\": \"$type\");
Run Code Online (Sandbox Code Playgroud)


Dej*_*jan 5

我必须为UI REST API做到这一点,因为Angular.js 会忽略以美元符号($)开头的字段名称。

因此,这里有一个解决方案,$type可以__type为整个Web API 重命名为,并且可以用于序列化反序列化。

为了能够使用自定义JsonWriter和自定义JsonReader(如该问题的其他答案所述),我们必须继承JsonMediaTypeFormatter和覆盖相应的方法:

internal class CustomJsonNetFormatter : JsonMediaTypeFormatter
{
    public override JsonReader CreateJsonReader(Type type, Stream readStream, Encoding effectiveEncoding)
    {
        return new CustomJsonReader(readStream, effectiveEncoding);
    }

    public override JsonWriter CreateJsonWriter(Type type, Stream writeStream, Encoding effectiveEncoding)
    {
        return new CustomJsonWriter(writeStream, effectiveEncoding);
    }

    private class CustomJsonWriter : JsonTextWriter
    {
        public CustomJsonWriter(Stream writeStream, Encoding effectiveEncoding)
            : base(new StreamWriter(writeStream, effectiveEncoding))
        {
        }

        public override void WritePropertyName(string name, bool escape)
        {
            if (name == "$type") name = "__type";
            base.WritePropertyName(name, escape);
        }
    }

    private class CustomJsonReader : JsonTextReader
    {
        public CustomJsonReader(Stream readStream, Encoding effectiveEncoding)
            : base(new StreamReader(readStream, effectiveEncoding))
        {
        }

        public override bool Read()
        {
            var hasToken = base.Read();
            if (hasToken && TokenType == JsonToken.PropertyName && Value != null && Value.Equals("__type"))
            {
                SetToken(JsonToken.PropertyName, "$type");
            }
            return hasToken;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您需要在中注册自定义格式器WebApiConfig。因此,我们将默认的Json.NET格式化程序替换为自定义的格式化程序:

config.Formatters.Remove(config.Formatters.JsonFormatter);
config.Formatters.Add(new CustomJsonNetFormatter());
Run Code Online (Sandbox Code Playgroud)

做完了