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

在另一个类中使用时,如何实现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{ ... }