Tengo una clase que contiene una enum
propiedad, y al serializar el objeto usando JavaScriptSerializer
, mi resultado json contiene el valor entero de la enumeración en lugar de su string
"nombre". ¿Hay alguna manera de obtener la enumeración como a string
en mi json sin tener que crear una costumbre JavaScriptConverter
? ¿Quizás hay un atributo con el que podría decorar la enum
definición o propiedad del objeto?
Como ejemplo:
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
Gender Gender { get; set; }
}
Resultado json deseado:
{ "Age": 35, "Gender": "Male" }
Lo ideal es buscar una respuesta con las clases integradas de .NET Framework, si no son posibles alternativas (como Json.net) son bienvenidas.
Respuestas:
No, no hay ningún atributo especial que pueda usar.
JavaScriptSerializer
serializaenums
a sus valores numéricos y no a su representación de cadena. Tendría que usar la serialización personalizada para serializarenum
como su nombre en lugar de su valor numérico.Si puede usar JSON.Net en lugar de
JavaScriptSerializer
ver la respuesta a esta pregunta proporcionada por OmerBakhari : JSON.net cubre este caso de uso (a través del atributo[JsonConverter(typeof(StringEnumConverter))]
) y muchos otros que no son manejados por los serializadores .net incorporados. Aquí hay un enlace que compara las características y funcionalidades de los serializadores .fuente
JsonConverter
no funcionará.Descubrí que Json.NET proporciona la funcionalidad exacta que busco con un
StringEnumConverter
atributo:Más detalles disponibles en la
StringEnumConverter
documentación .Hay otros lugares para configurar este convertidor de manera más global:
enum si quieres que enum siempre se serialice / deserialice como cadena
En caso de que alguien quiera evitar la decoración de atributos, puede agregar el convertidor a su JsonSerializer (sugerido por Bjørn Egil ):
y funcionará para cada enumeración que vea durante esa serialización (sugerido por Travis ).
o JsonConverter (sugerido por banana ):
Además, puede controlar la carcasa y si los números aún se aceptan utilizando el constructor StringEnumConverter (NamingStrategy, Boolean) .
fuente
Controller
o anular manualmente cada serialización.camelCase
salida):new StringEnumConverter { CamelCaseText = true }
Agregue lo siguiente a su global.asax para la serialización JSON de c # enum como cadena
fuente
Formatting
aIndented
?La respuesta @Iggy establece la serialización JSON de c # enum como cadena solo para ASP.NET (API web, etc.).
Pero para que funcione también con la serialización ad hoc, agregue siguiente a su clase de inicio (como Global.asax Application_Start)
Más información en la página de Json.NET
Además, para que su miembro de enumeración serialice / deserialice a / de un texto específico, use el
atributo, como este:
fuente
[EnumMember]
.CamelCaseText
propiedad ahora está marcada como obsoleta. Nueva forma de instanciar el convertidor:new StringEnumConverter(new CamelCaseNamingStrategy())
No pude cambiar el modelo de origen como en la respuesta superior (de @ob.), Y no quería registrarlo globalmente como @Iggy. Por lo que combinado https://stackoverflow.com/a/2870420/237091 y @ de Iggy https://stackoverflow.com/a/18152942/237091 para permitir la creación de la cadena de convertidor de enumeración durante el propio comando SerializeObject:
fuente
La combinación de las respuestas de Omer Bokhari y uri es siempre mi solución, ya que los valores que quiero proporcionar suelen ser diferentes de los que tengo en mi enumeración, especialmente que me gustaría poder cambiar mis enumeraciones si fuera necesario.
Entonces, si alguien está interesado, es algo como esto:
fuente
JsonPropertyAttribute
para miembros de enumeración y está trabajando para tareas de deserialización simples. Lamentablemente, durante los ajustes manuales conJToken
s se ignora. HappillyEnumMemberAttribute
funciona a las mil maravillas . ¡Gracias!JavaScriptSerializer
?Esto se hace fácilmente mediante la adición de un
ScriptIgnore
atributo a laGender
propiedad, haciendo que no se puede serializar, y añadiendo unaGenderString
propiedad que no conseguir serializado:fuente
Esta versión de la respuesta de Stephen no cambia el nombre en el JSON:
fuente
DataContractJsonSerializer
noJavaScriptSerializer
Aquí está la respuesta para newtonsoft.json
fuente
true
a su tipo JsonConverter de esta manera:[JsonConverter(typeof(StringEnumConverter), true)]
ASP.NET Core way:
https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
fuente
También puede agregar un convertidor a su
JsonSerializer
si no desea utilizar elJsonConverter
atributo:Funcionará para todo
enum
lo que vea durante esa serialización.fuente
Aquí hay una solución simple que serializa una enumeración de C # del lado del servidor a JSON y utiliza el resultado para completar un
<select>
elemento del lado del cliente . Esto funciona tanto para enumeraciones simples como para enumeraciones de bitflag.He incluido la solución de extremo a extremo porque creo que la mayoría de las personas que desean serializar una enumeración de C # a JSON probablemente también la usarán para completar un
<select>
menú desplegable.Aquí va:
Ejemplo de enumeración
Una enumeración compleja que utiliza OR bit a bit para generar un sistema de permisos. Por lo tanto, no puede confiar en el índice simple [0,1,2 ..] para el valor entero de la enumeración.
Lado del servidor - C #
El código anterior usa el marco NancyFX para manejar la solicitud Get. Utiliza el
Response.AsJson()
método auxiliar de Nancy, pero no se preocupe, puede usar cualquier formateador JSON estándar ya que la enumeración ya se ha proyectado en un tipo anónimo simple listo para la serialización.JSON generado
Lado del cliente - CoffeeScript
HTML antes
HTML después
fuente
Para ASP.Net core Solo agregue lo siguiente a su clase de inicio:
fuente
Puede crear JsonSerializerSettings con la llamada a JsonConverter.SerializeObject de la siguiente manera:
fuente
Notó que no hay respuesta para la serialización cuando hay un atributo Descripción.
Aquí está mi implementación que admite el atributo Descripción.
Enum:
Uso:
fuente
Para .Net Core: -
fuente
Microsoft.AspNetCore.Mvc.Formatters.Json
paquete NuGet, parece ser solo un método de extensión activadoIMvcCoreBuilder
, noIMvcBuilder
. Entonces se usa comoservices.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
.En .net core 3 esto ahora es posible con las clases integradas en System.Text.Json:
Para configurar
JsonStringEnumConverter
con decoración de atributos para la propiedad específica:Si desea convertir siempre la enumeración como cadena, coloque el atributo en la enumeración misma.
fuente
Asp.Net Core 3 con System.Text.Json
fuente
En caso de que alguien encuentre lo anterior insuficiente, terminé resolviéndome con esta sobrecarga:
fuente
Esta es una vieja pregunta, pero pensé que contribuiría por si acaso. En mis proyectos, uso modelos separados para cualquier solicitud de Json. Un modelo normalmente tendría el mismo nombre que el objeto de dominio con el prefijo "Json". Los modelos se asignan usando AutoMapper . Al hacer que el modelo json declare una propiedad de cadena que es una enumeración en la clase de dominio, AutoMapper resolverá su presentación de cadena.
En caso de que se pregunte, necesito modelos separados para las clases serializadas de Json porque el serializador incorporado viene con referencias circulares de lo contrario.
Espero que esto ayude a alguien.
fuente
En realidad, puede usar un convertidor de JavaScript para lograr esto con el JavaScriptSerializer incorporado. Al convertir su enumeración en un Uri, puede codificarlo como una cadena.
Describí cómo hacer esto para las fechas, pero también se puede usar para enumeraciones. Formato JSON de fecha y hora personalizado para .NET JavaScriptSerializer .
fuente
No estoy seguro de si esto sigue siendo relevante, pero tuve que escribir directamente en un archivo json y se me ocurrió la siguiente combinación de varias respuestas de stackoverflow juntas
Asegura que todas mis claves json están en minúsculas comenzando de acuerdo con las "reglas" json. Da formato a una sangría limpia e ignora los nulos en la salida. Además, al agregar un StringEnumConverter, imprime enumeraciones con su valor de cadena.
Personalmente, creo que es lo más limpio que se me ocurrió, sin tener que ensuciar el modelo con anotaciones.
uso:
fuente
He reunido todas las piezas de esta solución usando la
Newtonsoft.Json
biblioteca. Soluciona el problema de enumeración y también hace que el manejo de errores sea mucho mejor, y funciona en los servicios alojados de IIS. Es bastante código, por lo que puede encontrarlo en GitHub aquí: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.csDebe agregar algunas entradas a su
Web.config
para que funcione, puede ver un archivo de ejemplo aquí: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.configfuente
Y para VB.net encontré los siguientes trabajos:
fuente
Una opción un poco más a prueba de futuro
Enfrentando la misma pregunta, determinamos que necesitábamos una versión personalizada de
StringEnumConverter
para asegurarnos de que nuestros valores de enumeración podrían expandirse con el tiempo sin romperse catastróficamente en el lado de deserialización (ver el fondo a continuación). Utilizando elSafeEnumConverter
siguiente permite que finalice la deserialización, incluso si la carga útil contiene un valor para la enumeración que no tiene una definición con nombre, más cerca de cómo funcionaría la conversión de int a enumeración.Uso:
o
Fuente:
Antecedentes
Cuando analizamos el uso de
StringEnumConverter
, el problema que tuvimos fue que también necesitábamos pasividad para los casos en que se agregaba un nuevo valor de enumeración, pero no todos los clientes se daban cuenta de inmediato del nuevo valor. En estos casos, elStringEnumConverter
paquete con Newtonsoft JSON arroja un valorJsonSerializationException
similar a "Error al convertir el valor SomeString para escribir EnumType" y luego falla todo el proceso de deserialización. Esto fue un factor decisivo para nosotros, porque incluso si el cliente planeaba ignorar / descartar el valor de la propiedad que no entendía, ¡todavía tenía que ser capaz de deserializar el resto de la carga útil!fuente
fuente
fuente