c# json serialization json.net

c# - Json.Net: Serializar/Deserializar propiedad como un valor, no como un objeto



serialization (2)

Puede agregar un TypeConverter para StringId . Json.NET recogerá el convertidor de tipos y lo usará para convertirlo desde y hacia una cadena:

[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); } }

Si su representación de cadena contiene datos numéricos o de fecha / hora incrustados, asegúrese de convertir esos datos utilizando la culture pasada en lugar de la cultura actual predeterminada. Json.NET llamará al convertidor con la cultura correcta, que es la cultura invariante por defecto , asegurando así que los archivos JSON generados sean portables entre culturas.

fiddle muestra.

Sin embargo, tenga en cuenta que, si está utilizando .Net Core, la compatibilidad con los convertidores de tipo solo se agregó a partir de Json.NET 10.0.1 . Y la compatibilidad con convertidores de tipo en las compilaciones portátiles de Json.NET no está disponible a partir de 10.0.3.

Alternativamente, si no le importa agregar atributos específicos de Json.NET a su tipo, puede usar un JsonConverter personalizado :

[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); } }

También puede configurar el convertidor en la configuración global .

fiddle muestra.

¿Cómo puedo lograr la siguiente representación JSON de la clase Id cuando se usa en otra clase?

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


Puede anular el método ToString de la clase StringId para devolver el valor

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

Necesitará un TypeConverter más tarde para deserializar de string a 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); } }

Y decora tu clase StringId con este atributo

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