Por qué la serialización de enum es un dolor de cabeza para todo desarrollador de C#
\n\n¿Alguna vez se ha encontrado en una situación en la que su código C# ordenado, que trabaja con enumeraciones (enum), de repente comienza a mostrar números extraños en lugar de nombres claros? Si es así, no está solo. La pregunta "JavaScriptSerializer - JSON serialization of enum as string" en Stack Overflow ha acumulado miles de visitas, lo que significa que el problema es conocido por muchos.
\n\nAverigüemos por qué JavaScriptSerializer por defecto convierte sus hermosos nombres de enum en números sin rostro y, lo más importante, cómo solucionarlo de una vez por todas.
\n\nEl problema: ¿por qué el enum se convierte en un número?
\n\nPor defecto, JavaScriptSerializer (clase del espacio de nombres System.Web.Script.Serialization) serializa las enumeraciones como sus valores enteros. Esto se debe a que cada enum se basa en un número entero (int por defecto).
public enum Status\n{\n Active = 1,\n Inactive = 2,\n Pending = 3\n}\n\npublic class Order\n{\n public int Id { get; set; }\n public Status OrderStatus { get; set; }\n}\n\n// Serialización\nvar order = new Order { Id = 1, OrderStatus = Status.Active };\nvar serializer = new JavaScriptSerializer();\nstring json = serializer.Serialize(order);\n// Resultado: {"Id":1,"OrderStatus":1}\n\n\nEstará de acuerdo en que "OrderStatus":1 parece poco informativo. Imagine que ese JSON se envía a una API: el código del cliente tendrá que adivinar qué significa el número 1.
Top 5 errores al trabajar con JavaScriptSerializer y enum
\n\nError 1: Uso de EnumMemberAttribute sin configuración
\n\nMuchos desarrolladores intentan aplicar [EnumMember] del espacio System.Runtime.Serialization, pensando que esto resolverá el problema. Pero JavaScriptSerializer no procesa este atributo por defecto.
[DataContract]\npublic enum Status\n{\n [EnumMember(Value = "active")]\n Active = 1,\n [EnumMember(Value = "inactive")]\n Inactive = 2\n}\n\n// JavaScriptSerializer igualmente mostrará números\n\n\nError 2: Ignorar ScriptIgnoreAttribute
\n\nAlgunos intentan ocultar la propiedad del enum y luego agregar una representación de cadena por separado. Esto complica el código y rompe la integridad de los datos.
\n\nError 3: Conversión manual mediante if/switch
\n\nEl "parche" más común es crear una propiedad de cadena adicional y realizar la conversión manual:
\n\npublic class Order\n{\n public int Id { get; set; }\n public Status OrderStatus { get; set; }\n \n // Duplicación de datos: mala práctica\n public string OrderStatusString\n {\n get { return OrderStatus.ToString(); }\n }\n}\n\n\nProblema: ahora tiene dos propiedades que deben sincronizarse. Tarde o temprano se desincronizarán.
\n\nError 4: Olvidar la distinción entre mayúsculas y minúsculas
\n\nIncluso si logra la serialización, el código del cliente puede esperar "active", pero recibirá "Active". La diferencia en mayúsculas/minúsculas provoca errores en el lado de JavaScript.
Error 5: Usar el obsoleto JavaScriptSerializer en lugar de Newtonsoft.Json
\n\nLa clase JavaScriptSerializer se considera obsoleta en las versiones modernas de .NET. Microsoft recomienda usar System.Text.Json o Newtonsoft.Json. Pero si trabaja con un proyecto heredado o Web Forms, no podrá evitarlo.
Cómo serializar correctamente un enum a cadena: 3 soluciones funcionales
\n\nSolución 1: Convertidor personalizado (método recomendado)
\n\nCree su propia clase que herede de JavaScriptConverter y regístrela en el serializador.
public class EnumToStringConverter<T> : JavaScriptConverter where T : struct\n{\n public override IEnumerable<Type> SupportedTypes\n