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{
...
}