繁体   English   中英

Json.Net:将属性序列化/反序列化为值,而不是对象

[英]Json.Net: Serialize/Deserialize property as a value, not as an object

在另一个类中使用时,如何实现 Id 类的以下 JSON 表示?

class Car
{
    public StringId Id { get; set; }
    public string Name { get; set; }
}

class StringId
{
    public string Value { get; set; }
}

// ---------------------------------------------

// Desired representation
{ "Id": "someId", "Name": "Ford" }

// Default (undesired) representation
{ "Id" : { "Value": "someId" }, "Name": "Ford" }

您可以为StringId添加一个TypeConverter Json.NET 将选择类型转换器并使用它来将其从字符串转换为字符串:

[TypeConverter(typeof(StringIdConverter))]
class StringId
{
    public string Value { get; set; }
}

class StringIdConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(StringId))
            return true;
        return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value is string)
        {
            return new StringId { Value = (string)value };
        }
        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is StringId)
        {
            return ((StringId)value).Value;
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

如果您的字符串表示包含嵌入的数字或日期/时间数据,请确保使用传入的culture而不是默认的当前区域性来转换该数据。 Json.NET 将使用正确的文化调用转换器, 默认情况下这是不变的文化,从而确保生成的 JSON 文件在文化之间可移植。

样品小提琴

但是请注意,如果您使用的是 .Net Core,则仅从Json.NET 10.0.1 起添加了对类型转换器的支持。 从 10.0.3 开始,不支持 Json.NET Portable 版本中的类型转换器。

或者,如果您不介意将 Json.NET 特定的属性添加到您的类型,您可以使用自定义JsonConverter

[JsonConverter(typeof(StringIdConverter))]
class StringId
{
    public string Value { get; set; }
}

class StringIdConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(StringId);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader);
        return new StringId { Value = (string)token };
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var id = (StringId)value;
        writer.WriteValue(id.Value);
    }
}

您还可以在全局设置中设置转换器。

样品小提琴

您可以重写StringId类的ToString方法以返回值

    public override string ToString()
    {
        return this.Value;
    }

稍后您将需要一个TypeConverter来将字符串反序列StringId

public class StringIdConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }


    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string)
        {
            return new StringId(value.ToString());
        }
        return base.ConvertFrom(context, culture, value);
    }
}

并使用此属性装饰您的StringId

[TypeConverter(typeof(StringIdConverter))]
public class StringId{
    ...
}

暂无
暂无

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

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