【问题标题】:Serialization - C# Data Types序列化 - C# 数据类型
【发布时间】:2018-08-01 05:48:11
【问题描述】:

我有一个希望序列化为 JSON 的对象,但我宁愿让每个属性都有其关联的类型,而不是每个属性都有其关联的值。

例如,我有以下课程:

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public bool IsMarried { get; set; }
}

我想要的结果 JSON 看起来像这样

{
    "Student:" {
       "Name": "String",
       "Age": "Int",
       "DateOfBirth": "DateTime",
       "IsMarried": "Boolean"
    }
}

有没有办法可以设置JsonSerializer 来序列化每个属性的type 而不是value?

【问题讨论】:

标签: c# json serialization


【解决方案1】:

使用来自this答案的信息来构建自定义JsonSerializer,您可以修改WriteJson方法来指定您要写入的信息。

构建自定义JsonSerializer 需要创建一个新类并从JsonSerializer 派生它,然后覆盖您有兴趣自定义的任何方法。

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    if (value == null)
    {
        serializer.Serialize(writer, null);
        return;
    }

    var properties = value.GetType().GetProperties();

    writer.WriteStartObject();

    foreach (var property in properties)
    {
        // Write the property name
        writer.WritePropertyName(property.Name);
        // Get the value of the property and get the type
        serializer.Serialize(writer, property.GetValue(value, null).GetType());
    }

    writer.WriteEndObject();
}

【讨论】:

    【解决方案2】:

    修改Ian H. 的回答我能够创建一个自定义JsonConverter 来处理将属性类型写入JSON。

    public class CustomConverter : JsonConverter
    {
        private readonly Type[] _types;
    
        public CustomConverter(params Type[] types)
        {
            _types = types;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (value == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
    
            var properties = value.GetType().GetProperties();
    
            writer.WriteStartObject();
    
            foreach (var property in properties)
            {
                // Write the property name
                writer.WritePropertyName(property.Name);
                // Get the property type name of the property
                serializer.Serialize(writer, property.PropertyType.Name);
            }
    
            writer.WriteEndObject();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override bool CanConvert(Type objectType)
        {
            return _types.Any(t => t == objectType);
        }
    }
    

    使用我的另一个自定义类,每个属性都是一个字符串,在尝试转换该类的新实例时,每个属性值都是null,因此调用property.GetValue(value, null).GetType() 会抛出NullReferenceException。

    因此,我将那行代码替换为property.PropertyType.Name,效果很好!

    【讨论】:

    • 不错!直到现在才知道PropertyName 的存在,找到了!
    • writer.WriteStartObject() 和 writer.WriteEndObject() 行是干什么用的?
    • AFAIK 他们将开头{ 和结尾} 的指标写入JsonWriter。
    猜你喜欢
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多