serializar - recorrer json c#
Deserializar el carácter json como enumeración. (3)
Este código funciona perfectamente:
CardType[] array = { CardType.Artist, CardType.Contemporary };
string s = JsonConvert.SerializeObject(array);
var array2 = JsonConvert.DeserializeObject<CardType[]>(s);
Actualización :
¿Qué pasa con StringEnumConverter
fuera de la caja:
[JsonConverter(typeof(StringEnumConverter))]
public CardType Type { get; set; }
Tengo una enumeración definida con C #, donde almaceno sus valores como caracteres, como este:
public enum CardType
{
Artist = ''A'',
Contemporary = ''C'',
Historical = ''H'',
Musician = ''M'',
Sports = ''S'',
Writer = ''W''
}
Estoy intentando deserializar usando JSON.NET, pero el JSON entrante se escribió usando el valor CHAR (cadena) en lugar del valor int de la enumeración, como esto:
[{"CardType","A"},{"CardType", "C"}]
¿Es posible definir algún tipo de convertidor que me permita analizar manualmente el valor char a la enumeración?
Intenté crear un JsonConverter, pero no estoy seguro de cómo hacerlo, mientras lo aplico solo a esta propiedad y no a todo el objeto analizado. esto es lo que intenté:
public class EnumerationConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
int value = serializer.Deserialize<int>(reader);
return (CardType)value;
}
public override bool CanConvert(Type objectType)
{
return objectType.IsSubclassOf(typeof(string));
}
}
La lógica puede estar equivocada y puedo solucionarlo, pero el problema es que ReadJson () no se está llamando en absoluto.
CanConvert es, pero parece que se llama para cada propiedad, no solo la propiedad para la que lo definí:
public class Card
{
private CardType type;
[JsonConverter(typeof(EnumerationConverter))]
public CardType Type
{
get { return type; }
set { type = value; }
}
}
Estoy seguro de que hice esto incorrectamente, pero tengo problemas para encontrar documentación sobre cómo hacer esto para un solo campo ...
¿Qué me estoy perdiendo?
No es necesario que necesite un JsonConverter
personalizado, puede utilizar el StringEnumConverter
con la combinación del EnumMemberAttribute
(del ensamblaje System.Runtime.Serialization
).
Sin el EnumMemberAttribute
, utiliza los nombres de enumeración de Artista, Contemporáneo, etc., por lo que debe cambiar los nombres con este a su valor A, C, etc.
Pero no es la mejor solución porque tiene que repetir sus valores dos veces, pero funciona:
[JsonConverter(typeof(StringEnumConverter))]
public enum CardType
{
[EnumMember(Value = "A")]
Artist = ''A'',
[EnumMember(Value = "C")]
Contemporary = ''C'',
[EnumMember(Value = "H")]
Historical = ''H'',
[EnumMember(Value = "M")]
Musician = ''M'',
[EnumMember(Value = "S")]
Sports = ''S'',
[EnumMember(Value = "W")]
Writer = ''W''
}
Simplemente puede agregar SerializerSettings.Converters.Add (new StringEnumConverter ());
a su clase BrowserJsonFormatter
public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
public BrowserJsonFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
SerializerSettings.Formatting = Formatting.Indented;
SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
SerializerSettings.Converters.Add(new EmptyToNullConverter());
SerializerSettings.Converters.Add(new StringEnumConverter());
//SerializerSettings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}