在Json.NET

时间:2017-02-01 00:51:30

标签: c# json json.net

我正在使用Unity3D中的Json.NET(v90r1)的Net20库,我正在尝试使用Json.NET来序列化Type类型的字段。

我发现FormatterAssemblyStyle会影响自动生成的类型信息,但它似乎不会影响Type类型的字段。例如:

using Newtonsoft.Json;
using System.Runtime.Serialization.Formatters;
using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        var settings = new JsonSerializerSettings() {
            Formatting = Formatting.Indented,
            TypeNameHandling = TypeNameHandling.All,
            TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
        };

        Debug.Log(JsonConvert.SerializeObject(new Foo(), settings));
    }
}

public class Foo
{
    public System.Type type = typeof(void);
}

这将产生以下JSON字符串:

{
  "$type": "Foo, Assembly-CSharp",
  "type": "System.Void, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
}

如您所见,FormatterAssemblyStyle.Simple已用于$type,但FormatterAssemblyStyle.Full已用于type

这是我想要的输出:

{
  "$type": "Foo, Assembly-CSharp",
  "type": "System.Void, mscorlib"
}

如何使两种类型的打印方式相同?我找不到答案,因为大多数搜索结果都与序列化私有成员或使用类型信息序列化类而不是序列化包含类型的类有关。

1 个答案:

答案 0 :(得分:4)

根据sources

__asm

如果对象类型属于internal static bool TryConvertToString(object value, Type type, out string s) { //... type = value as Type; if (type != null) { s = type.AssemblyQualifiedName; return true; } //... } 类型,则格式为Type.AssemblyQualifiedName

但是,您可以按照CustomJsonConverter示例为Type创建自定义转换器:

Type

并使用如:

public class TypeConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (typeof(System.Type).IsAssignableFrom(value.GetType()))
        {
            // here you decide how much information you really want to dump
            Type type = (Type)value;
            writer.WriteValue(type.FullName + ", " + type.Assembly.GetName().Name);
        }
        else 
        {
            JToken t = JToken.FromObject(value);
            t.WriteTo(writer);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(System.Type).IsAssignableFrom(objectType);
    }
}