本文介绍了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" }

推荐答案

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

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,则仅从 Json.NET 10.0.1.从 10.0.3 开始,不支持 Json.NET Portable 版本中的类型转换器.

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 特定的属性添加到您的类型,您可以使用 自定义JsonConverter:

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.

示例 fiddle.

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

08-14 05:35