Tengo una estructura de datos que utilizamos para realizar llamadas de actualización de API a TFS y configuramos la propiedad Value como genérica que funciona bien. Nos gustaría usar enumeraciones en nuestro código de cliente como representaciones de algunos tipos, pero se serializan como enteros. Entonces, existe la opción [JsonConvert(typeof(StringEnumConverter))], en un genérico este es un problema, ya que intenta serializar todos los valores como una cadena contra el tipo de enumeración de la propiedad. Se parece a esto:

public class WorkItemUpdateData<T> : WorkItemUpdate
{
    [JsonConverter(typeof(StringEnumConverter))]
    [JsonProperty("value")]
    public T Value { get; set; }
}

¿Es posible aplicar el convertidor condicionalmente cuando la propiedad T es enum solamente?

0
Stephen York 15 abr. 2020 a las 07:55

2 respuestas

¿Podría ser más fácil "clasificar" esto, tener un WorkItemUpdateData y un WorkItemUpdateEnumData? Entonces su lógica condicional para que se aplique el JsonConverter se puede hacer al crear el objeto en lugar de al serializarlo.

public class WorkItemUpdateData<T> : WorkItemUpdate
{
    [JsonConverter(typeof(StringEnumConverter))]
    [JsonProperty("value")]
    public T Value { get; set; }
}

public class WorkItemUpdateEnumData<T> : WorkItemUpdate
{
    [JsonProperty("value")]
    public T Value { get; set; }
}

También puede incluir algo en los setters para asegurarse de que se usen correctamente, como

if (!typeof(T).IsEnum) throw ... 
0
Jeff Whitty 15 abr. 2020 a las 06:25

Al implementar un convertidor personalizado y especificar esto como convertidor:

public class OnlyEnumStringConverter : StringEnumConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value != null && value.GetType().IsEnum)
        {
            base.WriteJson(writer, value, serializer);
        }
        else
        {
            serializer.Serialize(writer, value);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (objectType.IsEnum)
        {
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }
        else
        {
            return serializer.Deserialize(reader, objectType);
        }
    }
}

Especificándolo:

public class WorkItemUpdateData<T> : WorkItemUpdate
{
    [JsonConverter(typeof(OnlyEnumStringConverter))]
    [JsonProperty("value")]
    public T Value { get; set; }
}
0
Oguz Ozgul 15 abr. 2020 a las 07:12