J'ai une classe qui contient une enum
propriété, et lors de la sérialisation de l'objet à l'aide JavaScriptSerializer
, mon résultat json contient la valeur entière de l'énumération plutôt que son string
"nom". Existe-t-il un moyen d'obtenir l'énumération en tant que string
dans mon json sans avoir à créer de personnalisation JavaScriptConverter
? Peut-être y a-t-il un attribut avec lequel je pourrais décorer la enum
définition ou la propriété de l'objet?
Par exemple:
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
Gender Gender { get; set; }
}
Résultat json souhaité:
{ "Age": 35, "Gender": "Male" }
Idéalement à la recherche d'une réponse avec des classes de framework .NET intégrées, sinon des alternatives possibles (comme Json.net) sont les bienvenues.
Réponses:
Non, vous ne pouvez utiliser aucun attribut spécial.
JavaScriptSerializer
sérialiseenums
à leurs valeurs numériques et non à leur représentation sous forme de chaîne. Vous devez utiliser une sérialisation personnalisée pour sérialiser le enenum
tant que son nom au lieu d'une valeur numérique.Si vous pouvez utiliser JSON.Net au lieu de
JavaScriptSerializer
voir la réponse à cette question fournie par OmerBakhari : JSON.net couvre ce cas d'utilisation (via l'attribut[JsonConverter(typeof(StringEnumConverter))]
) et bien d'autres non traités par les sérialiseurs .net intégrés. Voici un lien comparant les caractéristiques et fonctionnalités des sérialiseurs .la source
JsonConverter
ne fonctionnera pas.J'ai trouvé que Json.NET fournit la fonctionnalité exacte que je recherche avec un
StringEnumConverter
attribut:Plus de détails sur disponibles sur la
StringEnumConverter
documentation .Il existe d'autres endroits pour configurer ce convertisseur de manière plus globale:
enum lui-même si vous voulez que enum soit toujours sérialisé / désérialisé en tant que chaîne:
Si quelqu'un veut éviter la décoration d'attributs, vous pouvez ajouter le convertisseur à votre JsonSerializer (suggéré par Bjørn Egil ):
et cela fonctionnera pour chaque énumération qu'il verra pendant cette sérialisation (suggérée par Travis ).
ou JsonConverter (suggéré par la banane ):
De plus, vous pouvez contrôler la casse et si les nombres sont toujours acceptés à l'aide du constructeur StringEnumConverter (NamingStrategy, Boolean) .
la source
Controller
ou remplacer manuellement chaque sérialisation.camelCase
sortie):new StringEnumConverter { CamelCaseText = true }
Ajoutez ce qui suit à votre global.asax pour la sérialisation JSON de c # enum en tant que chaîne
la source
Formatting
àIndented
?@Iggy answer définit la sérialisation JSON de c # enum comme chaîne uniquement pour ASP.NET (API Web, etc.).
Mais pour que cela fonctionne également avec la sérialisation ad hoc, ajoutez le suivant à votre classe de démarrage (comme Global.asax Application_Start)
Plus d'information sur la page Json.NET
De plus, pour que votre membre enum sérialise / désérialise vers / depuis un texte spécifique, utilisez le
attribut, comme ceci:
la source
[EnumMember]
.CamelCaseText
propriété est désormais marquée comme obsolète. Nouvelle façon d'instancier le convertisseur:new StringEnumConverter(new CamelCaseNamingStrategy())
Je n'ai pas pu changer le modèle source comme dans la première réponse (de @ob.), Et je ne voulais pas l'enregistrer globalement comme @Iggy. Donc , je combine https://stackoverflow.com/a/2870420/237091 et @ Iggy https://stackoverflow.com/a/18152942/237091 pour permettre la mise en place du convertisseur de chaîne sur ENUM au cours de la commande serialiseObjet lui - même:
la source
La combinaison de Omer Bokhari et des réponses d'uri est toujours ma solution car les valeurs que je veux fournir sont généralement différentes de ce que j'ai dans mon énumération spécialement que j'aimerais pouvoir changer mes énumérations si j'en ai besoin.
Donc, si quelqu'un est intéressé, c'est quelque chose comme ceci:
la source
JsonPropertyAttribute
pour les membres enum et cela fonctionne pour des tâches de désérialisation simples. Malheureusement, lors des réglages manuels avecJToken
s, il est ignoré. HeureusementEnumMemberAttribute
fonctionne comme un charme. Merci!JavaScriptSerializer
?Cela se fait facilement en ajoutant un
ScriptIgnore
attribut à laGender
propriété, ceGenderString
qui empêche sa sérialisation et en ajoutant une propriété qui est sérialisée:la source
Cette version de la réponse de Stephen ne change pas le nom dans le JSON:
la source
DataContractJsonSerializer
nonJavaScriptSerializer
Voici la réponse pour newtonsoft.json
la source
true
à votre type JsonConverter comme ceci:[JsonConverter(typeof(StringEnumConverter), true)]
Méthode ASP.NET Core:
https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
la source
Vous pouvez également ajouter un convertisseur à votre
JsonSerializer
si vous ne souhaitez pas utiliser d'JsonConverter
attribut:Cela fonctionnera pour tout
enum
ce qu'il verra pendant cette sérialisation.la source
Voici une solution simple qui sérialise une énumération C # côté serveur en JSON et utilise le résultat pour remplir un côté client
<select>
élément . Cela fonctionne pour les énumérations simples et les énumérations bitflag.J'ai inclus la solution de bout en bout parce que je pense que la plupart des gens qui souhaitent sérialiser une énumération C # en JSON l'utiliseront probablement aussi pour remplir une liste
<select>
déroulante.Voici:
Exemple d'énumération
Une énumération complexe qui utilise des OR au niveau du bit pour générer un système d'autorisations. Vous ne pouvez donc pas vous fier à l'index simple [0,1,2 ..] pour la valeur entière de l'énumération.
Côté serveur - C #
Le code ci-dessus utilise le framework NancyFX pour gérer la demande Get. Il utilise la
Response.AsJson()
méthode d'assistance de Nancy - mais ne vous inquiétez pas, vous pouvez utiliser n'importe quel formateur JSON standard car l'énumération a déjà été projetée dans un type anonyme simple prêt pour la sérialisation.JSON généré
Côté client - CoffeeScript
HTML avant
HTML après
la source
Pour le noyau ASP.Net Ajoutez simplement les éléments suivants à votre classe de démarrage:
la source
Vous pouvez créer JsonSerializerSettings avec l'appel à JsonConverter.SerializeObject comme ci-dessous:
la source
A remarqué qu'il n'y a pas de réponse pour la sérialisation quand il y a un attribut Description.
Voici mon implémentation qui prend en charge l'attribut Description.
Enum:
Usage:
la source
Pour .Net Core: -
la source
Microsoft.AspNetCore.Mvc.Formatters.Json
package NuGet, il semble que ce ne soit qu'une méthode d'extensionIMvcCoreBuilder
, nonIMvcBuilder
. Il est donc utilisé commeservices.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
.Dans .net core 3, cela est désormais possible avec les classes intégrées dans System.Text.Json:
Pour configurer
JsonStringEnumConverter
avec une décoration d'attribut pour la propriété spécifique:Si vous souhaitez toujours convertir l'énumération en chaîne, placez l'attribut sur l'énumération elle-même.
la source
Asp.Net Core 3 avec System.Text.Json
la source
Juste au cas où quelqu'un trouverait ce qui précède insuffisant, j'ai fini par me contenter de cette surcharge:
la source
C'est une vieille question mais j'ai pensé que je contribuerais juste au cas où. Dans mes projets, j'utilise des modèles distincts pour toutes les demandes Json. Un modèle aurait généralement le même nom que l'objet de domaine avec le préfixe "Json". Les modèles sont mappés à l'aide d' AutoMapper . En faisant en sorte que le modèle json déclare une propriété de chaîne qui est une énumération sur la classe de domaine, AutoMapper se résout à sa présentation de chaîne.
Au cas où vous vous poseriez la question, j'ai besoin de modèles distincts pour les classes sérialisées Json car le sérialiseur intégré contient des références circulaires dans le cas contraire.
J'espère que cela aide quelqu'un.
la source
Vous pouvez réellement utiliser un JavaScriptConverter pour y parvenir avec le JavaScriptSerializer intégré. En convertissant votre énumération en Uri, vous pouvez l'encoder sous forme de chaîne.
J'ai décrit comment faire cela pour les dates, mais il peut également être utilisé pour les énumérations. Format JSON DateTime personnalisé pour .NET JavaScriptSerializer .
la source
Je ne sais pas si cela est toujours pertinent, mais j'ai dû écrire directement dans un fichier json et j'ai trouvé les réponses suivantes regroupant plusieurs réponses stackoverflow ensemble
Cela garantit que toutes mes clés json sont en minuscules en commençant selon les "règles" json. Le formate proprement en retrait et ignore les valeurs nulles dans la sortie. De plus, en ajoutant un StringEnumConverter, il imprime les énumérations avec leur valeur de chaîne.
Personnellement, je trouve cela le plus propre possible, sans avoir à salir le modèle avec des annotations.
usage:
la source
J'ai rassemblé tous les éléments de cette solution en utilisant la
Newtonsoft.Json
bibliothèque. Il résout le problème d'énumération et améliore également la gestion des erreurs, et il fonctionne dans les services hébergés IIS. C'est beaucoup de code, vous pouvez donc le trouver sur GitHub ici: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.csVous devez ajouter quelques entrées à votre
Web.config
pour le faire fonctionner, vous pouvez voir un exemple de fichier ici: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.configla source
Et pour VB.net, j'ai trouvé les œuvres suivantes:
la source
Une option légèrement plus évolutive
Face à la même question, nous avons déterminé que nous avions besoin d'une version personnalisée de
StringEnumConverter
pour nous assurer que nos valeurs d'énumération pouvaient s'étendre au fil du temps sans se casser de manière catastrophique du côté de la désérialisation (voir arrière-plan ci-dessous). En utilisant leSafeEnumConverter
suit permet à la désérialisation de se terminer même si la charge utile contient une valeur pour l'énumération qui n'a pas de définition nommée, plus proche du fonctionnement de la conversion int-en-énumération.Usage:
ou
La source:
Contexte
Lorsque nous avons envisagé d'utiliser le
StringEnumConverter
, le problème que nous avions était que nous avions également besoin de passivité pour les cas où une nouvelle valeur d'énumération était ajoutée, mais tous les clients n'étaient pas immédiatement conscients de la nouvelle valeur. Dans ces cas, leStringEnumConverter
package avec Newtonsoft JSON renvoie un messageJsonSerializationException
similaire à «Erreur lors de la conversion de la valeur SomeString en type EnumType», puis l' ensemble du processus de désérialisation échoue. C'était une rupture pour nous, car même si le client prévoyait d'ignorer / de rejeter la valeur de la propriété qu'il ne comprenait pas, il devait toujours être capable de désérialiser le reste de la charge utile!la source
la source
la source