.net - 如何在 JsonConverter 中将数组转换为对象

标签 .net json.net serialization

我想使用 JsonConverter 将属性的类型从数组更改为对象.例如,我有这样一个属性 [{"Name":"aaa"}] .序列化后我想要这样的结果 {"__po":"Add",Objects:[{"Name":"aaa"}]} .

所以我创建了一个类来自定义我的序列化程序:

public class Serializer : ISerializer
{
    public JsonSerializerSettings SerializerSettings { get; set; }

    public Serializer()
    {
        SerializerSettings = new JsonSerializerSettings();
        SerializerSettings.Converters.Add(new ParseArrayToObjectJsonConverter());
    }

    public class ParseArrayToObjectJsonConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            if (objectType.GetTypeInfo().Name.EndsWith("Array"))
            {
                return true;
            }
            return false;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {

        }
    }
}

我看到了 JsonWriter有这个属性public WriteState WriteState { get; }它可以返回这样的枚举:public enum WriteState { Error = 0, Closed = 1, Object = 2, Array = 3, Constructor = 4, Property = 5, Start = 6 } .

在我的WriteJson方法,writer.WriteState 的类型是WriteState.Array , 但问题是我无法设置 WriteState 的值用于返回一个对象。您还有其他解决方案来处理这个问题吗?

最佳答案

我认为您误解了如何在 JsonConverter 中使用 JsonWriter。您永远不需要弄乱作者的 WriteState。它是一个只读属性,指示作者当前正在编写的内容。您不能直接更改它。相反,您应该使用作者的 WriteXxx() 方法来实际写出您想要的 JSON。以下是如何实现将数组包装在对象中的 JsonConverter:

public class WrapArrayInObjectJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        // This will cause the converter to wrap ALL IEnumerables (except strings) in an object.
        return typeof(IEnumerable).IsAssignableFrom(objectType) && objectType != typeof(string);

        // If you only want to this converter to wrap specific kinds of arrays, change this
        // method accordingly.  For example, this will only wrap Foo[] or List<Foo>:
        //return typeof(IEnumerable<Foo>).IsAssignableFrom(objectType);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        IEnumerable array = (IEnumerable)value;
        writer.WriteStartObject();
        writer.WritePropertyName("__po");
        writer.WriteValue("Add");
        writer.WritePropertyName("Objects");
        writer.WriteStartArray();
        foreach (object item in array)
        {
            serializer.Serialize(writer, item);
        }
        writer.WriteEndArray();
        writer.WriteEndObject();
    }

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

下面是一个使用转换器的例子:

Foo[] array = new Foo[]
{
    new Foo { Name = "aaa" },
    new Foo { Name = "bbb" }
};

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new WrapArrayInObjectJsonConverter());

string json = JsonConvert.SerializeObject(array, settings);
Console.WriteLine(json);

输出:

{"__po":"Add","Objects":[{"Name":"aaa"},{"Name":"bbb"}]}

fiddle :https://dotnetfiddle.net/79mXF2

关于.net - 如何在 JsonConverter 中将数组转换为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40679962/

相关文章:

c++ - Boost:如何在方法内部反序列化?

c# - 有没有可靠的方法来确定文本文件?

c# - 序列化列表计数而不是列表

c# - 自定义 JSON.NET 转换器,将字符串转换为类型

javascript - Passport JS : Is it possible to not serialize a user when connecting an account?

javascript - 如何使用变量值将 List<object> 序列化为 JSON?

c# - 使用 LINQ 对列值进行排序,忽略空字符串值

c# - LINQ to XML 不返回任何结果

c# - 用于对集合列表进行排序的 Lambda 表达式

c# - 通过自定义 IContractResolver 修改/添加属性