Mam klasę, która zawiera enum
właściwość, a po serializacji obiektu przy użyciu JavaScriptSerializer
mój wynik json zawiera wartość całkowitą wyliczenia, a nie jego string
„nazwę”. Czy istnieje sposób, aby uzyskać wyliczenie jako string
w moim Jsonie bez konieczności tworzenia niestandardowego JavaScriptConverter
? Być może istnieje atrybut, za pomocą którego mógłbym ozdobić enum
definicję lub właściwość obiektu?
Jako przykład:
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
Gender Gender { get; set; }
}
Pożądany wynik JSON:
{ "Age": 35, "Gender": "Male" }
Idealnie szukając odpowiedzi z wbudowanymi klasami .NET, jeśli nie możliwe, mile widziane są alternatywy (takie jak Json.net).
Odpowiedzi:
Nie, nie ma specjalnego atrybutu, którego można użyć.
JavaScriptSerializer
serializujeenums
do ich wartości liczbowych, a nie ich reprezentacji ciągu. Aby serializować nazwęenum
jako nazwę zamiast wartości liczbowej, należy użyć niestandardowej serializacji .Jeśli możesz użyć JSON.Net zamiast
JavaScriptSerializer
zobaczyć odpowiedź na to pytanie dostarczone przez OmerBakhari : JSON.net obejmuje ten przypadek użycia (poprzez atrybut[JsonConverter(typeof(StringEnumConverter))]
) i wiele innych nieobsługiwanych przez wbudowane serializatory .net. Oto link porównujący funkcje i funkcje serializatorów .źródło
JsonConverter
nie zadziała.Odkryłem, że Json.NET zapewnia dokładnie tę funkcjonalność, której szukam z
StringEnumConverter
atrybutem:Więcej szczegółów dostępnych w
StringEnumConverter
dokumentacji .Istnieją inne miejsca, w których można skonfigurować ten konwerter bardziej globalnie:
samo wyliczanie, jeśli chcesz, wyliczanie zawsze jest serializowane / deserializowane jako ciąg:
Jeśli ktoś chce uniknąć dekorowania atrybutów, możesz dodać konwerter do JsonSerializer (sugerowany przez Bjørn Egil ):
i będzie działać dla każdego wyliczenia, które zobaczy podczas tej serializacji (sugerowane przez Travisa ).
lub JsonConverter (sugerowany przez banana ):
Dodatkowo możesz kontrolować obudowę i to, czy liczby są nadal akceptowane za pomocą konstruktora StringEnumConverter (NamingStrategy, Boolean) .
źródło
Controller
lub ręcznie zastąpić każdą serializację.camelCase
wyjściu):new StringEnumConverter { CamelCaseText = true }
Dodaj poniższy kod do pliku global.asax w celu uzyskania serializacji JSON enum c # jako łańcucha
źródło
Formatting
sięIndented
?Odpowiedź @Iggy ustawia serializację JSON wyliczenia c # jako ciąg tylko dla ASP.NET (Web API i tak dalej).
Aby jednak działał również z serializacją ad hoc, dodaj następujące elementy do swojej klasy początkowej (np. Global.asax Application_Start)
Więcej informacji na stronie Json.NET
Dodatkowo, aby twój członek enum szeregował / deserializował do / z określonego tekstu, użyj
atrybut, taki jak ten:
źródło
[EnumMember]
.CamelCaseText
Właściwość jest teraz oznaczone nieaktualne. Nowy sposób na utworzenie instancji konwertera:new StringEnumConverter(new CamelCaseNamingStrategy())
Nie byłem w stanie zmienić modelu źródłowego jak w górnej odpowiedzi (@ob.) I nie chciałem go rejestrować globalnie jak @Iggy. Więc połączyłem https://stackoverflow.com/a/2870420/237091 i @ Iggy's https://stackoverflow.com/a/18152942/237091, aby umożliwić skonfigurowanie konwertera wyliczania ciągów podczas samej komendy SerializeObject:
źródło
Kombinacja odpowiedzi Omera Bokhari i uri jest zawsze moim rozwiązaniem, ponieważ wartości, które chcę podać, zwykle różnią się od tych, które mam w swoim wyliczeniu, szczególnie że chciałbym móc zmienić moje wyliczenia, jeśli zajdzie taka potrzeba.
Jeśli więc ktoś jest zainteresowany, może to wyglądać mniej więcej tak:
źródło
JsonPropertyAttribute
dla członków enum i działa dla prostych zadań deserializtion. Niestety podczas ręcznych poprawek za pomocąJToken
s jest ignorowany. HappillyEnumMemberAttribute
działa jak urok. Dzięki!JavaScriptSerializer
?Można to łatwo zrobić, dodając
ScriptIgnore
atrybut doGender
właściwości, powodując, że nie jest ona serializowana, i dodającGenderString
właściwość, która jest serializowana:źródło
Ta wersja Stefana odpowiedź nie zmienia nazwę w JSON:
źródło
DataContractJsonSerializer
nieJavaScriptSerializer
Oto odpowiedź dla newtonsoft.json
źródło
true
do swojego typu JsonConverter w następujący sposób:[JsonConverter(typeof(StringEnumConverter), true)]
Sposób ASP.NET Core:
https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
źródło
Możesz także dodać konwerter,
JsonSerializer
jeśli nie chcesz używaćJsonConverter
atrybutu:Będzie działać dla każdego,
enum
co zobaczy podczas tej serializacji.źródło
Oto proste rozwiązanie, które serializuje wyliczenie C # po stronie serwera do JSON i wykorzystuje wynik do wypełnienia po stronie klienta
<select>
elementu po . Działa to zarówno dla prostych, jak i dla bitflagów.Zawarłem kompleksowe rozwiązanie, ponieważ myślę, że większość osób chcących serializować wyliczenie C # do JSON również prawdopodobnie użyje go do wypełnienia listy
<select>
rozwijanej.Tutaj idzie:
Przykład Enum
Złożony wyliczenie, które wykorzystuje bitowe OR do generowania systemu uprawnień. Dlatego nie można polegać na prostym indeksie [0,1,2 ..] dla wartości całkowitej wyliczenia.
Po stronie serwera - C #
Powyższy kod używa struktury NancyFX do obsługi żądania Get. Wykorzystuje Nancy
Response.AsJson()
metodę pomocniczą - ale nie martw się, możesz użyć dowolnego standardowego formatyzatora JSON, ponieważ wyliczenie zostało już zaprojektowane w prosty anonimowy typ gotowy do serializacji.Wygenerowano JSON
Strona klienta - CoffeeScript
HTML przed
HTML After
źródło
Dla rdzenia ASP.Net Po prostu dodaj następujące elementy do klasy startowej:
źródło
Możesz utworzyć JsonSerializerSettings za pomocą wywołania JsonConverter.SerializeObject, jak poniżej:
źródło
Zauważyliśmy, że nie ma odpowiedzi na serializację, gdy istnieje atrybut Opis.
Oto moja implementacja, która obsługuje atrybut Opis.
Enum:
Stosowanie:
źródło
Dla .Net Core: -
źródło
Microsoft.AspNetCore.Mvc.Formatters.Json
pakietu NuGet, wydaje się, że jest to tylko metoda rozszerzeniaIMvcCoreBuilder
, a nieIMvcBuilder
. Więc jest używany jakservices.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
.W .net core 3 jest to teraz możliwe dzięki wbudowanym klasom w System.Text.Json:
Aby skonfigurować
JsonStringEnumConverter
z dekoracją atrybutu dla określonej właściwości:Jeśli chcesz zawsze konwertować wyliczenie jako ciąg, umieść atrybut w samym wyliczeniu.
źródło
Asp.Net Core 3 z System.Text.Json
źródło
Na wypadek, gdyby ktokolwiek uznał powyższe za niewystarczające, skończyłem z tym przeciążeniem:
źródło
To stare pytanie, ale pomyślałem, że na wszelki wypadek. W moich projektach używam osobnych modeli dla wszystkich żądań Json. Model zazwyczaj miałby taką samą nazwę jak obiekt domeny z prefiksem „Json”. Modele są mapowane za pomocą AutoMapper . Dzięki temu, że model json deklaruje właściwość ciągu będącą wyliczeniem klasy domeny, AutoMapper rozpoznaje prezentację ciągu.
Jeśli się zastanawiasz, potrzebuję osobnych modeli dla serializowanych klas Jsona, ponieważ wbudowany serializator zawiera odwołania cykliczne.
Mam nadzieję, że to komuś pomoże.
źródło
Możesz faktycznie użyć JavaScriptConverter, aby to zrobić za pomocą wbudowanego JavaScriptSerializer. Konwertując swoje wyliczenie na Uri, możesz zakodować je jako ciąg.
Opisałem, jak to zrobić dla dat, ale można go również użyć do wyliczeń. Niestandardowy format JSON DateTime dla .NET JavaScriptSerializer .
źródło
Nie jestem pewien, czy to nadal jest istotne, ale musiałem napisać prosto do pliku JSON i wymyśliłem następujący sposób składania kilku odpowiedzi przepełnienia stosu
Zapewnia to, że wszystkie moje klucze json są pisane małymi literami, zgodnie z „regułami” json. Formatuje czyste wcięcie i ignoruje wartości zerowe w danych wyjściowych. Również dodając StringEnumConverter drukuje wyliczenia z ich wartością ciągu.
Osobiście uważam, że jest to najczystszy sposób, jaki mogłem wymyślić, bez konieczności brudzenia modelu adnotacjami.
stosowanie:
źródło
Złożyłem wszystkie elementy tego rozwiązania za pomocą
Newtonsoft.Json
biblioteki. Rozwiązuje problem wyliczania, a także znacznie poprawia obsługę błędów i działa w usługach hostowanych w IIS. To całkiem sporo kodu, więc możesz go znaleźć na GitHub tutaj: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.csMusisz dodać kilka wpisów do swojego
Web.config
, aby działało, możesz zobaczyć przykładowy plik tutaj: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.configźródło
A dla VB.net znalazłem następujące prace:
źródło
Nieco bardziej przyszłościowa opcja
W obliczu tego samego pytania ustaliliśmy, że potrzebujemy niestandardowej wersji,
StringEnumConverter
aby upewnić się, że nasze wartości wyliczeniowe mogą się rozszerzać w czasie, nie niszcząc katastrofalnie po deserializującej stronie (patrz tło poniżej). UżywającSafeEnumConverter
poniższego pozwala na zakończenie deserializacji, nawet jeśli ładunek zawiera wartość wyliczenia, która nie ma nazwanej definicji, bliżej do tego, jak działałaby konwersja zamiany na wyliczanie.Stosowanie:
lub
Źródło:
tło
Kiedy spojrzeliśmy na użycie
StringEnumConverter
, mieliśmy problem, że potrzebowaliśmy również pasywności w przypadkach, gdy dodano nową wartość wyliczenia, ale nie każdy klient od razu wiedział o nowej wartości. W takich przypadkachStringEnumConverter
pakiet z Newtonoft JSON generujeJsonSerializationException
błąd podobny do „Błąd konwersji wartości SomeString na typ EnumType”, a następnie cały proces deserializacji kończy się niepowodzeniem. Było to dla nas przełomowe, ponieważ nawet jeśli klient planował zignorować / odrzucić wartość nieruchomości, której nie rozumiał, nadal musiał być zdolny do deserializacji reszty ładunku!źródło
źródło
źródło