Json.Net:序列化/反序列化属性是一个值,而不是一个对象 [英] Json.Net: Serialize/Deserialize property as a value, not as an object

查看:89
本文介绍了Json.Net:序列化/反序列化属性是一个值,而不是一个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I achieve the following JSON representation of Id class when used in another class?

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" }

推荐答案

您可以添加

You could add a TypeConverter for StringId. Json.NET will pick up the type converter and use it to convert it from and to a string:

[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文件可在区域性之间移植.

If your string representation contains embedded numeric or date/time data, be sure to convert that data using the culture passed in rather than the default, current culture. Json.NET will call the converter with the correct culture, which is the invariant culture by default, thus ensuring the generated JSON files are portable between cultures.

样本小提琴.

但是请注意,如果您使用的是.Net Core,则仅在

Note however that, if you are using .Net Core, support for type converters was only added as of Json.NET 10.0.1. And support for type converters in Json.NET Portable builds is not available as of 10.0.3.

或者,如果您不介意向类型中添加特定于Json.NET的属性,则可以使用

Alternatively, if you don't mind adding Json.NET-specific attributes to your type, you could use a custom 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);
    }
}

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

You can also set the converter in global settings.

样本小提琴.

这篇关于Json.Net:序列化/反序列化属性是一个值,而不是一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆