У меня есть класс, который содержит enum
свойство, и после сериализации объекта JavaScriptSerializer
, мой результат json содержит целочисленное значение перечисления, а не его string
«имя». Есть ли способ получить enum как string
в моем json без необходимости создания кастома JavaScriptConverter
? Возможно, есть атрибут, которым я мог бы украсить enum
определение или свойство объекта?
Например:
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
Gender Gender { get; set; }
}
Желаемый результат JSON:
{ "Age": 35, "Gender": "Male" }
В идеале ищите ответ со встроенными классами .NET Framework, если не возможны альтернативы (например, Json.net).
Ответы:
Нет, нет специального атрибута, который вы можете использовать.
JavaScriptSerializer
сериализуетenums
их числовые значения, а не их строковое представление. Вам потребуется использовать пользовательскую сериализацию для сериализации вenum
качестве ее имени вместо числового значения.Если вы можете использовать JSON.Net вместо того,
JavaScriptSerializer
чтобы увидеть ответ на этот вопрос, предоставленный OmerBakhari : JSON.net охватывает этот вариант использования (через атрибут[JsonConverter(typeof(StringEnumConverter))]
) и многие другие, которые не обрабатываются встроенными сериализаторами .net. Вот ссылка, сравнивающая особенности и функциональность сериализаторов .источник
JsonConverter
не будет работать.Я обнаружил, что Json.NET предоставляет именно ту функцию, которую я ищу, с
StringEnumConverter
атрибутом:Более подробную информацию можно найти в
StringEnumConverter
документации .Есть другие места, чтобы настроить этот конвертер более глобально:
сам enum, если вы хотите, чтобы enum всегда был сериализован / десериализован как строка:
Если кто-то хочет избежать украшения атрибутов, вы можете добавить конвертер в свой JsonSerializer (предложенный Бьорном Эгилом ):
и он будет работать для каждого перечисления, которое он видит во время этой сериализации (предложено Трэвисом ).
или JsonConverter (предложенный бананом ):
Кроме того, вы можете контролировать регистр и принимать ли числа, используя конструктор StringEnumConverter (NamingStrategy, Boolean) .
источник
Controller
или вручную переопределять каждую сериализацию.camelCase
вывода):new StringEnumConverter { CamelCaseText = true }
Добавьте ниже в ваш global.asax для JSON сериализации c # enum в виде строки
источник
Formatting
кIndented
?Ответ @Iggy устанавливает JSON-сериализацию c # enum в виде строки только для ASP.NET (веб-API и т. Д.).
Но чтобы заставить его работать и с специальной сериализацией, добавьте следующее в ваш начальный класс (например, Global.asax Application_Start)
Больше информации на странице Json.NET
Кроме того, чтобы ваш член enum мог сериализовать / десериализовать определенный текст, используйте
атрибут, как это:
источник
[EnumMember]
.CamelCaseText
Свойство теперь помечается как устаревшее. Новый способ создания экземпляра конвертера:new StringEnumConverter(new CamelCaseNamingStrategy())
Я не смог изменить исходную модель, как в верхнем ответе (@ob.), И я не хотел регистрировать ее глобально, как @Iggy. Поэтому я объединил https://stackoverflow.com/a/2870420/237091 и @ Iggy's https://stackoverflow.com/a/18152942/237091, чтобы разрешить настройку преобразователя перечисления строк во время самой команды SerializeObject:
источник
Комбинация ответов Omer Bokhari и uri всегда является моим решением, так как ценности, которые я хочу предоставить, обычно отличаются от того, что у меня есть в моем enum, особенно в том, что я хотел бы иметь возможность изменять свои перечисления, если мне это нужно.
Так что, если кому-то интересно, это что-то вроде этого:
источник
JsonPropertyAttribute
для членов enum, и это работает для простых задач десериализации. К сожалению, при ручной настройке сJToken
s он игнорируется. HappillyEnumMemberAttribute
работает как шарм. Спасибо!JavaScriptSerializer
?Это легко сделать, добавив
ScriptIgnore
атрибут вGender
собственности, в результате чего он не сериализации, и добавивGenderString
свойство , которое делает получить сериализации:источник
Эта версия ответа Стивена не меняет имя в JSON:
источник
DataContractJsonSerializer
неJavaScriptSerializer
Вот ответ для newtonsoft.json
источник
true
к вашему типу JsonConverter, например, следующее:[JsonConverter(typeof(StringEnumConverter), true)]
Основной способ ASP.NET:
https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
источник
Вы также можете добавить конвертер,
JsonSerializer
если вы не хотите использоватьJsonConverter
атрибут:Это будет работать для каждого, что
enum
он видит во время этой сериализации.источник
Вот простое решение, которое сериализует перечисление C # на стороне сервера в JSON и использует результат для заполнения
<select>
элемента на стороне клиента . Это работает как для простых перечислений, так и для битовых флагов.Я включил комплексное решение, потому что я думаю, что большинство людей, желающих сериализовать перечисление C # в JSON, также, вероятно, будут использовать его для заполнения
<select>
раскрывающегося списка.Поехали:
Пример Enum
Сложное перечисление, которое использует побитовые ИЛИ для генерации системы разрешений. Таким образом, вы не можете полагаться на простой индекс [0,1,2 ..] для целочисленного значения перечисления.
Сторона сервера - C #
Приведенный выше код использует инфраструктуру NancyFX для обработки запроса Get. Он использует
Response.AsJson()
вспомогательный метод Нэнси - но не волнуйтесь, вы можете использовать любой стандартный форматер JSON, поскольку перечисление уже спроецировано в простой анонимный тип, готовый к сериализации.Сгенерированный JSON
Клиентская сторона - CoffeeScript
HTML раньше
HTML после
источник
Для ядра ASP.Net Просто добавьте следующее в свой класс запуска:
источник
Вы можете создать JsonSerializerSettings с помощью вызова JsonConverter.SerializeObject, как показано ниже:
источник
Заметил, что при сериализации нет ответа для сериализации.
Вот моя реализация, которая поддерживает атрибут Description.
Enum:
Применение:
источник
Для .Net Core: -
источник
Microsoft.AspNetCore.Mvc.Formatters.Json
пакета NuGet, кажется, это только метод расширенияIMvcCoreBuilder
, а неIMvcBuilder
. Так что используется какservices.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
.В .net core 3 это теперь возможно с помощью встроенных классов в System.Text.Json:
Для настройки
JsonStringEnumConverter
с оформлением атрибута для конкретного свойства:Если вы хотите всегда преобразовывать перечисление как строку, поместите атрибут в само перечисление.
источник
Asp.Net Core 3 с System.Text.Json
источник
На всякий случай, если кто-то сочтет это недостаточным, я согласился с этой перегрузкой:
источник
Это старый вопрос, но я решил внести свой вклад на всякий случай. В своих проектах я использую отдельные модели для любых запросов Json. Модель обычно имеет то же имя, что и объект домена с префиксом «Json». Модели отображаются с использованием AutoMapper . Если модель json объявит строковое свойство, являющееся перечислением класса домена, AutoMapper разрешит его представление строки.
Если вам интересно, мне нужны отдельные модели для сериализованных классов Json, потому что в противном случае встроенный сериализатор предлагает циклические ссылки.
Надеюсь, это кому-нибудь поможет.
источник
На самом деле вы можете использовать JavaScriptConverter для достижения этой цели с помощью встроенного JavaScriptSerializer. Преобразуя ваше перечисление в Uri, вы можете закодировать его как строку.
Я описал, как сделать это для дат, но это может быть использовано и для перечислений. Пользовательский формат DateTime JSON для .NET JavaScriptSerializer .
источник
Не уверен, что это все еще актуально, но я должен был написать прямо в файл json, и я придумал следующее объединение нескольких ответов stackoverflow
Это гарантирует, что все мои ключи JSON начинаются со строчной буквы в соответствии с «правилами» JSON. Форматирует его с чистым отступом и игнорирует нули в выходных данных. Также, добавив StringEnumConverter, он печатает перечисления с их строковым значением.
Лично я считаю, что это самое чистое, что я мог придумать, не пачкая модель аннотациями.
Применение:
источник
Я собрал все части этого решения, используя
Newtonsoft.Json
библиотеку. Он устраняет проблему с перечислением, а также значительно улучшает обработку ошибок и работает в службах, размещенных на IIS. Это довольно много кода, поэтому вы можете найти его на GitHub здесь: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.csВы должны добавить несколько записей к вашему,
Web.config
чтобы заставить его работать, вы можете увидеть файл примера здесь: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.configисточник
А для VB.net я нашел следующие работы:
источник
Чуть более перспективный вариант
Столкнувшись с тем же вопросом, мы определили, что нам нужна специальная версия,
StringEnumConverter
чтобы убедиться, что наши значения enum могут со временем увеличиваться без катастрофического разрушения на стороне десериализации (см. Фон ниже). С использованиемSafeEnumConverter
ниже позволяет десериализации завершиться, даже если полезная нагрузка содержит значение для перечисления, у которого нет именованного определения, ближе к тому, как будет работать преобразование int-в-перечисление.Применение:
или
Источник:
Фон
Когда мы смотрели на использование
StringEnumConverter
, мы столкнулись с проблемой, что нам также требовалась пассивность в тех случаях, когда добавлялось новое значение перечисления, но не каждый клиент сразу знал о новом значении. В этих случаяхStringEnumConverter
пакет с JSON Newtonsoft выдаетJsonSerializationException
аналогичное «Ошибка преобразования значения SomeString в тип EnumType», и тогда весь процесс десериализации завершается неудачно. Это стало для нас преградой, потому что даже если клиент планировал игнорировать / отбрасывать значение свойства, которое он не понимал, он все равно должен был быть способен десериализовать остальную часть полезной нагрузки!источник
источник
источник