Eu tenho uma classe que contém uma enum
propriedade e, após serializar o objeto JavaScriptSerializer
, meu resultado json contém o valor inteiro da enumeração, em vez de seu string
"nome". Existe uma maneira de obter a enumeração como string
no meu json sem ter que criar um costume JavaScriptConverter
? Talvez haja um atributo com o qual eu possa decorar a enum
definição ou propriedade de objeto?
Como um exemplo:
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
Gender Gender { get; set; }
}
Resultado json desejado:
{ "Age": 35, "Gender": "Male" }
O ideal é procurar respostas com classes de estrutura .NET integradas, se não forem possíveis alternativas (como Json.net).
Respostas:
Não, não há nenhum atributo especial que você possa usar.
JavaScriptSerializer
serializaenums
para seus valores numéricos e não para sua representação de string. Você precisaria usar a serialização personalizada para serializar oenum
nome como nome, em vez do valor numérico.Se você pode usar o JSON.Net em vez de
JavaScriptSerializer
ver a resposta dessa pergunta fornecida pelo OmerBakhari : o JSON.net cobre esse caso de uso (por meio do atributo[JsonConverter(typeof(StringEnumConverter))]
) e muitos outros não tratados pelos serializadores .net incorporados. Aqui está um link comparando recursos e funcionalidades dos serializadores .fonte
JsonConverter
não funcionará.Eu descobri que o Json.NET fornece a funcionalidade exata que estou procurando com um
StringEnumConverter
atributo:Mais detalhes estão disponíveis na
StringEnumConverter
documentação .Existem outros locais para configurar este conversor de maneira mais global:
enum se você quiser que o enum sempre seja serializado / desserializado como string:
Caso alguém queira evitar a decoração de atributos, você pode adicionar o conversor ao seu JsonSerializer (sugerido por Bjørn Egil ):
e funcionará para todas as enumerações exibidas durante a serialização (sugeridas por Travis ).
ou JsonConverter (sugerido por banana ):
Além disso, você pode controlar o caso e se os números ainda são aceitos usando o construtor StringEnumConverter (NamingStrategy, Boolean) .
fonte
Controller
ou substituir manualmente todas as serializações.camelCase
saída):new StringEnumConverter { CamelCaseText = true }
Adicione o seguinte ao global.asax para serialização JSON de c # enum como string
fonte
Formatting
paraIndented
?A resposta @Iggy define a serialização JSON de c # enum como string apenas para o ASP.NET (Web API e assim).
Mas, para fazê-lo funcionar também com a serialização ad hoc, adicione o seguinte à sua classe inicial (como Global.asax Application_Start)
Mais informações na página Json.NET
Além disso, para que seu membro enum serialize / desserialize de / para um texto específico, use o
atributo, assim:
fonte
[EnumMember]
.CamelCaseText
propriedade agora está marcada como obsoleta. Nova maneira de instanciar o conversor:new StringEnumConverter(new CamelCaseNamingStrategy())
Não consegui alterar o modelo de origem como na resposta superior (de @ob.) E não queria registrá-lo globalmente como @Iggy. Então eu combinei https://stackoverflow.com/a/2870420/237091 e @ de Iggy https://stackoverflow.com/a/18152942/237091 para permitir a configuração do conversor de corda enum durante o próprio comando SerializeObject:
fonte
A combinação das respostas de Omer Bokhari e uri é sempre a minha solução, já que os valores que eu quero fornecer geralmente são diferentes dos que tenho na minha enumeração, especialmente que eu gostaria de poder alterar minha enumeração, se necessário.
Portanto, se alguém estiver interessado, é algo como isto:
fonte
JsonPropertyAttribute
para membros enum e está trabalhando para tarefas simples de desserialização. Infelizmente, durante ajustes manuais comJToken
s, isso é ignorado. HappillyEnumMemberAttribute
funciona como um encanto. Obrigado!JavaScriptSerializer
?Isso é feito facilmente adicionando um
ScriptIgnore
atributo àGender
propriedade, fazendo com que ele não seja serializado e adicionando umaGenderString
propriedade que é serializada:fonte
Esta versão da resposta de Stephen não altera o nome no JSON:
fonte
DataContractJsonSerializer
nãoJavaScriptSerializer
Aqui está a resposta para newtonsoft.json
fonte
true
ao seu tipo JsonConverter desta maneira:[JsonConverter(typeof(StringEnumConverter), true)]
Maneira principal do ASP.NET:
https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
fonte
Você também pode adicionar um conversor ao seu
JsonSerializer
se não quiser usar oJsonConverter
atributo:Ele funcionará para tudo o
enum
que vir durante a serialização.fonte
Aqui está uma solução simples que serializa um C # enum do lado do servidor para JSON e usa o resultado para preencher um lado do cliente
<select>
elemento do . Isso funciona para enumerações simples e enumerações de bitflag.Eu incluí a solução de ponta a ponta porque acho que a maioria das pessoas que desejam serializar um enum C # para JSON também provavelmente o usará para preencher um
<select>
menu suspenso.Aqui vai:
Exemplo Enum
Um enum complexo que usa ORs bit a bit para gerar um sistema de permissões. Portanto, você não pode confiar no índice simples [0,1,2 ..] para o valor inteiro da enumeração.
Lado do servidor - C #
O código acima usa a estrutura NancyFX para manipular a solicitação Get. Ele usa o
Response.AsJson()
método auxiliar de Nancy - mas não se preocupe, você pode usar qualquer formatador JSON padrão, pois a enum já foi projetada em um tipo anônimo simples, pronto para serialização.JSON gerado
Lado do cliente - CoffeeScript
HTML Antes
HTML depois
fonte
Para o núcleo do ASP.Net, adicione o seguinte à sua classe de inicialização:
fonte
Você pode criar JsonSerializerSettings com a chamada para JsonConverter.SerializeObject como abaixo:
fonte
Percebeu que não há resposta para serialização quando há um atributo Descrição.
Aqui está minha implementação que suporta o atributo Descrição.
Enum:
Uso:
fonte
Para .Net Core: -
fonte
Microsoft.AspNetCore.Mvc.Formatters.Json
pacote NuGet, parece ser apenas um método de extensãoIMvcCoreBuilder
, nãoIMvcBuilder
. Então é usado assimservices.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
.Agora, no .net core 3, agora é possível com as classes internas no System.Text.Json:
Para configurar
JsonStringEnumConverter
com decoração de atributo para a propriedade específica:Se você deseja sempre converter o enum como string, coloque o atributo no próprio enum.
fonte
Asp.Net Core 3 com System.Text.Json
fonte
Apenas no caso de alguém achar o acima insuficiente, acabei resolvendo com essa sobrecarga:
fonte
Esta é uma pergunta antiga, mas pensei em contribuir apenas para o caso. Nos meus projetos, uso modelos separados para quaisquer solicitações Json. Um modelo normalmente teria o mesmo nome que o objeto de domínio com o prefixo "Json". Os modelos são mapeados usando o AutoMapper . Ao fazer com que o modelo json declare uma propriedade de string que é uma enumeração na classe de domínio, o AutoMapper resolverá sua apresentação de string.
Caso você esteja se perguntando, preciso de modelos separados para classes serializadas Json, pois o serializador embutido apresenta referências circulares.
Espero que isso ajude alguém.
fonte
Você pode realmente usar um JavaScriptConverter para fazer isso com o JavaScriptSerializer interno. Ao converter seu enum em um Uri, você pode codificá-lo como uma string.
Descrevi como fazer isso para datas, mas também pode ser usado para enumerações. Formato JSON DateTime personalizado para .NET JavaScriptSerializer .
fonte
Não tenho certeza se isso ainda é relevante, mas tive que escrever diretamente em um arquivo json e vim com as seguintes informações reunindo várias respostas de fluxo de pilha
Ele garante que todas as minhas chaves json sejam minúsculas, iniciando de acordo com as "regras" do json. Formata o recuo limpo e ignora valores nulos na saída. Além disso, adicionando um StringEnumConverter, ele imprime enumerações com seu valor de string.
Pessoalmente, acho isso o mais limpo possível, sem ter que sujar o modelo com anotações.
uso:
fonte
Reuni todas as partes desta solução usando a
Newtonsoft.Json
biblioteca. Ele corrige o problema da enumeração e também melhora o tratamento de erros e funciona nos serviços hospedados no IIS. É bastante código, então você pode encontrá-lo no GitHub aqui: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.csVocê precisa adicionar algumas entradas ao seu
Web.config
para que funcione. Você pode ver um arquivo de exemplo aqui: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.configfonte
E para VB.net eu encontrei os seguintes trabalhos:
fonte
Uma opção um pouco mais à prova de futuro
Enfrentando a mesma pergunta, determinamos que precisávamos de uma versão personalizada
StringEnumConverter
para garantir que nossos valores de enum pudessem se expandir ao longo do tempo sem quebrar catastroficamente no lado de desserialização (veja o plano de fundo abaixo). Usando oSafeEnumConverter
abaixo permite que a desserialização termine, mesmo que a carga útil contenha um valor para a enumeração que não tenha uma definição nomeada, mais próximo de como a conversão de intentenum funcionaria.Uso:
ou
Fonte:
fundo
Quando analisamos o uso do
StringEnumConverter
, o problema que tivemos é que também precisávamos de passividade para casos em que um novo valor de enum foi adicionado, mas nem todos os clientes estavam imediatamente cientes do novo valor. Nesses casos, oStringEnumConverter
empacotado com o Newtonsoft JSON lança umJsonSerializationException
semelhante a "Erro ao converter o valor SomeString para digitar EnumType" e, em seguida, todo o processo de desserialização falha. Isso foi um rompimento de negócios para nós, porque, mesmo que o cliente planejasse ignorar / descartar o valor da propriedade que não entendia, ainda precisava ser capaz de desserializar o restante da carga útil!fonte
fonte
fonte