繁体   English   中英

在Json.NET中使用FormatterAssemblyStyle.Simple序列化Type类型的字段

[英]Serialize field of type Type with FormatterAssemblyStyle.Simple in 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"
}

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

消息人士透露

internal static bool TryConvertToString(object value, Type type, out string s)
{
    //...
    type = value as Type;
    if (type != null)
    {
        s = type.AssemblyQualifiedName;
        return true;
    }
    //...
}

如果对象类型是Type类型,则将其格式化为Type.AssemblyQualifiedName

但是,您可以按照CustomJsonConverter示例为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);
    }
}

并使用如下:

    var settings = new JsonSerializerSettings()
    {
        Formatting = Formatting.Indented,
        TypeNameHandling = TypeNameHandling.All,
        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
        Converters = { new TypeConverter() } 
    };

    Console.WriteLine(JsonConvert.SerializeObject(new Foo(), settings));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM