JavaScriptSerializer-문자열로 열거 형의 JSON 직렬화


1160

enum속성 이 포함 된 클래스가 있고를 사용하여 객체를 직렬화하면 JavaScriptSerializerjson 결과에 string"name"이 아닌 열거의 정수 값이 포함 됩니다. string사용자 정의를 만들지 않고 json에서 열거 형을 얻을 수있는 방법이 JavaScriptConverter있습니까? 아마도 enum정의 또는 객체 속성을 장식 할 수있는 속성이 있습니까?

예로서:

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }
    Gender Gender { get; set; }
}

원하는 JSON 결과 :

{ "Age": 35, "Gender": "Male" }

내장 된 .NET 프레임 워크 클래스로 응답을 찾는 것이 이상적입니다 (Json.net과 같은) 가능한 대안은 환영합니다.


8
어느 것으로 바꾸시겠습니까? 가장 높은 평가를받은 답변은 실제로 질문에 답변하지 않습니다. 예, 다른 상황에서는 유용하므로 투표에 도움이되지만 MS JavaScriptSerializer에 갇혀 있으면 페이지 방법을 사용하는 경우와 같이 실용적으로 사용할 수 없습니다. 가장 중요한 것은 질문에서 요구하는 것입니다. 수락 된 답변은 불가능하다고 말합니다. 내 대답은 약간의 해킹이 작업을 완료하는 것입니다.
Stephen Kennedy

답변:


376

사용할 수있는 특별한 속성이 없습니다. 문자열 표현이 아닌 숫자 값으로 JavaScriptSerializer직렬화 enums합니다. enum숫자 값 대신 이름 을 직렬화하려면 사용자 정의 직렬화를 사용해야 합니다.


당신이 JSON.Net 대신 사용할 수있는 경우 JavaScriptSerializer에 비해 참조 이 질문에 답을 에서 제공 OmerBakhari : JSON.net이 사용 (속성을 통해 케이스 포함 [JsonConverter(typeof(StringEnumConverter))]) 및 .NET 시리얼에 내장 처리하지 많은 사람들을. 다음은 시리얼 라이저의 특징과 기능을 비교하는 링크 입니다.


7
@Fabzter - 솔루션이 Newtonsoft의 JSON 사용하여 저와 함께 일
BeemerGuy

1
@BornToCode Json.NET은 ASP.NET이 기본적으로 사용하는 시리얼 라이저입니다.
BrainSlugs83

12
@ BrainSlugs83-질문은 Json.NET이 아닌 JavaScriptSerializer를 사용하는 것에 관한 것입니다 (개정 기록을 보면 수정 내용이 있음을 알 수 있습니다). JavaScriptSerializer를 사용하면 속성 JsonConverter이 작동하지 않습니다.
BornToCode

50
문제를 해결하지 못하므로이 답변을 허용 된 답변으로 제거하십시오. 아래 답변은 1000 개 이상의 upvotes DOES입니다.
MHGameWork

당신이 나를 anwers 수
Yongqiang Chen

2101

Json.NET이 내가 찾고있는 정확한 기능 을 속성으로 제공 한다는 것을 알았습니다StringEnumConverter .

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }

자세한 내용은 설명서를 참조하십시오.StringEnumConverter .

이 변환기를보다 전역 적으로 구성 할 수있는 다른 장소가 있습니다.

  • 열거 형을 항상 문자열로 직렬화 / 직렬화 해제하려면 열거 형 자체 :

    [JsonConverter(typeof(StringEnumConverter))]  
    enum Gender { Male, Female }
  • 누구든지 속성 장식을 피하고 싶다면 JsonSerializer에 변환기를 추가 할 수 있습니다 ( Bjørn Egil 추천 ).

    serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); 

    그리고 그것은 직렬화 중에 보이는 모든 열거에 대해 작동합니다 ( Travis가 제안 함 ).

  • 또는 JsonConverter ( 바나나에서 제안 ) :

    JsonConvert.SerializeObject(MyObject, 
        new Newtonsoft.Json.Converters.StringEnumConverter());

또한 StringEnumConverter (NamingStrategy, Boolean) 생성자 를 사용하여 대 / 소문자를 제어 할 수 있습니다 .


9
asp.net mvc 응용 프로그램에서 사용하는 방법에 대한 설명을 보려면 링크를 따라하십시오. james.newtonking.com/archive/2008/10/16/…
RredCat

2
다음은 그 기능에 대한 링크입니다 : james.newtonking.com/projects/json/help/html/...은
CAD 놈

61
HttpConfiguration 구성 = GlobalConfiguration.Configuration; config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; config.Formatters.JsonFormatter.SerializerSettings.Converters.Add (new Newtonsoft.Json.Converters.StringEnumConverter ());
Iggy

1
기본적으로 ASP.NET MVC는 Json.Net을 json 직렬 변환기로 사용하지 않으며 Controller모든 직렬화를 확장 하거나 수동으로 재정의 해야합니다 .
Odys

2
변환기를 사용자 정의 할 수 있습니다 (예 camelCase: 출력).new StringEnumConverter { CamelCaseText = true }
Seafish

172

c # 열거 형의 JSON 직렬화를 위해 global.asax에 아래를 문자열로 추가하십시오.

  HttpConfiguration config = GlobalConfiguration.Configuration;
            config.Formatters.JsonFormatter.SerializerSettings.Formatting =
                Newtonsoft.Json.Formatting.Indented;

            config.Formatters.JsonFormatter.SerializerSettings.Converters.Add
                (new Newtonsoft.Json.Converters.StringEnumConverter());

4
어떤 이유로 든, 나는 이것이 작동하지 않습니다. 피들러는 '경고'보다는 완고한 2를 보여줍니다. 또한-왜 변경 Formatting해야 Indented합니까?
sq33G

5
이 예제의 세 번째 줄은 App_start / webapiconfig.cs 파일에 추가되었으며 ASP.NET Web API 2.1 프로젝트에서 REST (json fomat) 호출에서 열거 형 값의 문자열을 반환하는 속임수를 만들었습니다.
Greg Z.

1
요청 범위마다이 속성을 설정하는 방법이 있습니까?
Anestis Kivranoglou

@AnestisKivranoglou는 요청마다 고유 한 설정으로 사용자 정의 json serializer를 사용합니다.
BrainSlugs83

3
들여 쓰기의 첫 번째 serializer 설정은 op 질문과 관련이 없습니다.
user3791372

153

@Iggy 답변은 c # enum의 JSON 직렬화를 ASP.NET (웹 API 등)의 문자열로 설정합니다.

그러나 임시 직렬화에서도 작동하게하려면 시작 클래스에 다음을 추가하십시오 (예 : Global.asax Application_Start).

//convert Enums to Strings (instead of Integer) globally
JsonConvert.DefaultSettings = (() =>
{
    var settings = new JsonSerializerSettings();
    settings.Converters.Add(new StringEnumConverter { CamelCaseText = true });
    return settings;
});

추가 정보 Json.NET 페이지에 대한

또한 열거 형 멤버가 특정 텍스트를 직렬화 / 직렬화하도록하려면

System.Runtime.Serialization.EnumMember

다음과 같은 속성 :

public enum time_zone_enum
{
    [EnumMember(Value = "Europe/London")] 
    EuropeLondon,

    [EnumMember(Value = "US/Alaska")] 
    USAlaska
}

6
감사합니다! 나는 단지 찾고 있었다 [EnumMember].
Poulad

CamelCaseText속성은 이제 더 이상 사용되지 않습니다. 변환기를 인스턴스화하는 새로운 방법 :new StringEnumConverter(new CamelCaseNamingStrategy())
fiat

정말 감사합니다. :)
Eldoïr

39

@ob.의 최상위 답변과 같이 소스 모델을 변경할 수 없었으며 @Iggy와 같이 전역 적으로 등록하고 싶지 않았습니다. 따라서 https://stackoverflow.com/a/2870420/237091 과 @Iggy의 https://stackoverflow.com/a/18152942/237091 을 결합 하여 SerializeObject 명령 자체에서 문자열 열거 형 변환기를 설정할 수 있습니다.

Newtonsoft.Json.JsonConvert.SerializeObject(
    objectToSerialize, 
    Newtonsoft.Json.Formatting.None, 
    new Newtonsoft.Json.JsonSerializerSettings()
    {
        Converters = new List<Newtonsoft.Json.JsonConverter> {
            new Newtonsoft.Json.Converters.StringEnumConverter()
        }
    })

이 목록 <someEnumType>과 같은 속성이있는 경우이 또한 좋은를 웍
보그

34

Omer Bokhari와 uri의 대답의 조합은 항상 제공하려는 가치가 일반적으로 열거 형에있는 것과 다르기 때문에 필요에 따라 열거 형을 변경할 수 있기를 원하기 때문에 항상 해결책입니다.

관심있는 사람이라면 다음과 같습니다.

public enum Gender
{
   [EnumMember(Value = "male")] 
   Male,
   [EnumMember(Value = "female")] 
   Female
}

class Person
{
    int Age { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}

1
나는 JsonPropertyAttribute열거 형 멤버를 사용 하고 있었고 간단한 deserialize 작업을 위해 노력하고 있습니다. 슬프게도 JTokens로 수동 조정하는 동안 무시됩니다. Happilly EnumMemberAttribute는 매력처럼 작동합니다. 감사!
프롤로그

그것은 작동 JavaScriptSerializer합니까?
Stephen Kennedy

31

이것은 쉽게 추가하여 이루어집니다 ScriptIgnore받는 속성 Gender이 직렬화 할 수 없습니다 원인, 특성 및 추가 GenderString부동산 않습니다 직렬화 얻을를 :

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

    string GenderString { get { return Gender.ToString(); } }
}

29
설명하려고 노력하겠습니다. 이 솔루션은 디자인 패턴에 따라 올바르지 않습니다. 보기 목적에 따라 모델을 수정했습니다. 그러나 모델에는 데이터 만 포함되어야하며 프리젠 테이션에 신경 쓰지 않습니다. 이 기능을 다른 계층으로 이동해야합니다.
RredCat

4
실제로, Model은 프리젠 테이션에 신경 쓰지 않는 컨트롤러 인 컨트롤러에서 데이터를 전달하는 데 사용됩니다. 자동화 된 속성 (여기서는 GenderString)을 도입해도 여전히 Gender 속성을 사용하는 컨트롤러는 깨지지 않지만보기에 쉽게 액세스 할 수 있습니다. 논리적 솔루션.
Dima

17
@RredCat "뷰 모델"에 뷰 특정 속성을 갖는 데 아무런 문제가 없습니다. IMHO의 실수는 도메인 모델에서 뷰 모델을 분리하지 않는 것입니다 : blogs.msdn.com/b/simonince/archive/2010/01/26/…
Mariano Desanze

5
@RredCat, 일부 패턴에 따라 올바르지 않더라도 OP는 이에 대해 아무 것도 말하지 않으므로 실제로 정답입니다. (내가 철학적으로 당신의 요점에 동의 할지라도)
MEMark

10
이 댓글 스레드에서 놀랍도록 터무니없는 자전거 창고는 매혹적입니다.
Mike Mooney 1

26

이 버전의 Stephen의 답변 은 JSON의 이름을 변경하지 않습니다.

[DataContract(
    Namespace = 
       "http://schemas.datacontract.org/2004/07/Whatever")]
class Person
{
    [DataMember]
    int Age { get; set; }

    Gender Gender { get; set; }

    [DataMember(Name = "Gender")]
    string GenderString
    {
        get { return this.Gender.ToString(); }
        set 
        { 
            Gender g; 
            this.Gender = Enum.TryParse(value, true, out g) ? g : Gender.Male; 
        }
    }
}

3
나는 이것이 유효 DataContractJsonSerializer하지 않다고 생각한다JavaScriptSerializer
KCD

기본 .NET 프레임 워크 시리얼 라이저를 사용하여 간단하고 문제를 해결합니다.
상원 의원

나는 제 3의 라이브러리 (ISO의 complience 문제를) 사용할 수 없습니다입니다 나를위한 최적의 솔루션
다니엘 Gruszczyk을

이것은 물론 문제의 직렬 변환기 유형이 아닙니다. JavaScriptSerializer는 무시되지 않는 모든 항목을 직렬화하지만 DataContractJsonSerializer에는 DataMember 특성이 필요합니다. 소리 쳐 주셔서 감사하지만 내 이름을 잘못 입력했음을 참고하십시오 :)
Stephen Kennedy

25

다음은 newtonsoft.json에 대한 답변입니다.

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}

1
이 답변에 감사드립니다. PascalCase에서 열거 형을 정의하고 싶지만 camelCase에서 직렬화 true하려면 JsonConverter 유형에 다음과 같이 추가 해야합니다.[JsonConverter(typeof(StringEnumConverter), true)]
Peet


16

속성 JsonSerializer을 사용하지 않으려는 경우 변환기를 추가 할 수도 있습니다 JsonConverter.

string SerializedResponse = JsonConvert.SerializeObject(
     objToSerialize, 
     new Newtonsoft.Json.Converters.StringEnumConverter()
); 

enum해당 직렬화 중에 볼 때 마다 작동합니다 .


15

다음은 서버 측 C # 열거를 JSON으로 직렬화하고 결과를 사용하여 클라이언트 측을 채우는 간단한 솔루션입니다. <select> 요소 . 이것은 간단한 열거 형과 비트 플래그 열거 형 모두에서 작동합니다.

C # 열거 형을 JSON으로 직렬화하려는 대부분의 사람들이 <select>드롭 다운 을 채우는 데 사용할 것이라고 생각하기 때문에 엔드 투 엔드 솔루션을 포함 시켰 습니다.

간다 :

열거 형 예제

public enum Role
{
    None = Permission.None,
    Guest = Permission.Browse,
    Reader = Permission.Browse| Permission.Help ,
    Manager = Permission.Browse | Permission.Help | Permission.Customise
}

비트 단위 OR을 사용하여 권한 시스템을 생성하는 복잡한 열거 형입니다. 따라서 열거 형의 정수 값에 간단한 인덱스 [0,1,2 ..]를 사용할 수 없습니다.

서버 측-C #

Get["/roles"] = _ =>
{
    var type = typeof(Role);
    var data = Enum
        .GetNames(type)
        .Select(name => new 
            {
                Id = (int)Enum.Parse(type, name), 
                Name = name 
            })
        .ToArray();

    return Response.AsJson(data);
};

위의 코드는 NancyFX 프레임 워크를 사용하여 Get 요청을 처리합니다. 낸시를 사용합니다.Response.AsJson() 도우미 메서드를 하지만 열거 형이 이미 직렬화 준비가 된 간단한 익명 유형으로 투영되었으므로 표준 JSON 포맷터를 사용할 수 있습니다.

생성 된 JSON

[
    {"Id":0,"Name":"None"},
    {"Id":2097155,"Name":"Guest"},
    {"Id":2916367,"Name":"Reader"},
    {"Id":4186095,"Name":"Manager"}
]

클라이언트 쪽-CoffeeScript

fillSelect=(id, url, selectedValue=0)->
    $select = $ id
    $option = (item)-> $ "<option/>", 
        {
            value:"#{item.Id}"
            html:"#{item.Name}"
            selected:"selected" if item.Id is selectedValue
        }
    $.getJSON(url).done (data)->$option(item).appendTo $select for item in data

$ ->
    fillSelect "#role", "/roles", 2916367

HTML 전에

<select id="role" name="role"></select>

HTML 후

<select id="role" name="role">
    <option value="0">None</option>
    <option value="2097155">Guest</option>
    <option value="2916367" selected="selected">Reader</option>
    <option value="4186095">Manager</option>
</select>

13

ASP.Net 코어의 경우 시작 클래스에 다음을 추가하십시오.

JsonConvert.DefaultSettings = (() =>
        {
            var settings = new JsonSerializerSettings();
            settings.Converters.Add(new StringEnumConverter { AllowIntegerValues = false });
            return settings;
        });

1
이것은 코어뿐만 아니라 모든 버전에서 작동합니다.
bikeman868

11

아래와 같이 JsonConverter.SerializeObject를 호출하여 JsonSerializerSettings를 만들 수 있습니다.

var result = JsonConvert.SerializeObject
            (
                dataObject,
                new JsonSerializerSettings
                {
                    Converters = new [] {new StringEnumConverter()}
                }
            );

10

Description 속성이있는 경우 직렬화에 대한 응답이 없습니다.

다음은 Description 속성을 지원하는 구현입니다.

public class CustomStringEnumConverter : Newtonsoft.Json.Converters.StringEnumConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Type type = value.GetType() as Type;

        if (!type.IsEnum) throw new InvalidOperationException("Only type Enum is supported");
        foreach (var field in type.GetFields())
        {
            if (field.Name == value.ToString())
            {
                var attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
                writer.WriteValue(attribute != null ? attribute.Description : field.Name);

                return;
            }
        }

        throw new ArgumentException("Enum not found");
    }
}

열거 형 :

public enum FooEnum
{
    // Will be serialized as "Not Applicable"
    [Description("Not Applicable")]
    NotApplicable,

    // Will be serialized as "Applicable"
    Applicable
}

용법:

[JsonConverter(typeof(CustomStringEnumConverter))]
public FooEnum test { get; set; }

10

.Net Core의 경우 :-

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
    ...
}

2
이것이에서 하나의 경우 Microsoft.AspNetCore.Mvc.Formatters.JsonNuGet 패키지 만에 확장 방법이 될 것 같습니다 IMvcCoreBuilder하지 IMvcBuilder. 그래서처럼 사용됩니다 services.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));.
infl3x

9

.net core 3에서는 System.Text.Json의 내장 클래스를 통해 가능합니다.

var person = new Person();
// Create and add a converter which will use the string representation instead of the numeric value.
var stringEnumConverter = new System.Text.Json.Serialization.JsonStringEnumConverter();
JsonSerializerOptions opts = new JsonSerializerOptions();
opts.Converters.Add(stringEnumConverter);
// Generate json string.
var json = JsonSerializer.Serialize<Person>(person, opts);

JsonStringEnumConverter특정 속성에 대한 속성 장식으로 구성하려면

using System.Text.Json.Serialization;

[JsonConverter(typeof(JsonStringEnumConverter))]
public Gender Gender { get; set; }

열거 형을 항상 문자열로 변환하려면 속성을 열거 형 자체에 넣으십시오.

[JsonConverter(typeof(JsonStringEnumConverter))] 
enum Gender { Male, Female }

9

System.Text.Json이 포함 된 Asp.Net Core 3

public void ConfigureServices(IServiceCollection services)
{

    services
        .AddControllers()
        .AddJsonOptions(options => 
           options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())
        );

    //...
 }

8

누군가 위의 부족한 것을 발견하면이 과부하로 정착했습니다.

JsonConvert.SerializeObject(objToSerialize, Formatting.Indented, new Newtonsoft.Json.Converters.StringEnumConverter())

이것은 현재 사용 사례에 대한 좋은 솔루션입니다. 직렬 변환기 기본값을 변경하고 싶지 않으며 속성이 IList <EnumType> 유형이므로 속성을 사용하는 데 문제가 있습니다.
Dirk Brockhaus 2018 년

5

이것은 오래된 질문이지만, 만일을 대비하여 기여할 것이라고 생각했습니다. 내 프로젝트에서는 모든 Json 요청에 대해 별도의 모델을 사용합니다. 모델은 일반적으로 접두사가 "Json"인 도메인 개체와 이름이 같습니다. 모델은 AutoMapper를 사용하여 매핑됩니다 . json 모델이 도메인 클래스의 열거 형인 문자열 속성을 선언하게함으로써 AutoMapper는 문자열 표현으로 해석합니다.

궁금한 점이 있다면 내장 직렬 변환기가 순환 참조를 제공하기 때문에 Json 직렬화 클래스에 대한 별도의 모델이 필요합니다.

이것이 누군가를 돕기를 바랍니다.


Automapper ;-) [ScriptIgnore] 특성은 순환 참조를 제거합니다.
ledragon

1
오. 속성에 대해 몰랐습니다. 감사! Pocos에서 사용 하시겠습니까? Poco 속성에 MetadataType 정의를 사용하여 깔끔하게 유지했습니다. 메타 데이터를 통해 속성이 계속 작동합니까?
Ales Potocnik Hahonina


1

이것이 여전히 관련이 있는지 확실하지 않지만 json 파일에 직접 작성해야했고 몇 가지 stackoverflow 답변을 함께 정리했습니다.

public class LowercaseJsonSerializer
{
    private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        ContractResolver = new LowercaseContractResolver()
    };

    public static void Serialize(TextWriter file, object o)
    {
        JsonSerializer serializer = new JsonSerializer()
        {
            ContractResolver = new LowercaseContractResolver(),
            Formatting = Formatting.Indented,
            NullValueHandling = NullValueHandling.Ignore
        };
        serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
        serializer.Serialize(file, o);
    }

    public class LowercaseContractResolver : DefaultContractResolver
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            return Char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1);
        }
    }
}

json "rules"에 따라 모든 json 키가 소문자인지 확인합니다. 깨끗하게 들여 쓰기 된 형식으로 출력에서 ​​널을 무시합니다. 또한 StringEnumConverter를 추가하여 문자열 값으로 열거 형을 인쇄합니다.

개인적으로 나는 주석으로 모델을 더럽힐 필요없이 가장 깔끔하게 찾을 수 있습니다.

용법:

    internal void SaveJson(string fileName)
    {
        // serialize JSON directly to a file
        using (StreamWriter file = File.CreateText(@fileName))
        {
            LowercaseJsonSerializer.Serialize(file, jsonobject);
        }
    }

0

Newtonsoft.Json라이브러리를 사용 하여이 솔루션의 모든 부분을 모았습니다 . 열거 형 문제를 해결하고 오류 처리를 훨씬 개선하며 IIS 호스팅 서비스에서 작동합니다. 그것은 많은 코드이므로 GitHub에서 찾을 수 있습니다 : https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs

당신은 몇 가지 항목을 추가해야 할 Web.config일에 그걸 얻기 위해하는 것은, 당신이 예제 파일을 여기에서 볼 수 있습니다 https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config


0

그리고 VB.net의 경우 다음과 같은 작품을 발견했습니다.

Dim sec = New Newtonsoft.Json.Converters.StringEnumConverter()
sec.NamingStrategy() = New Serialization.CamelCaseNamingStrategy

Dim JSON_s As New JsonSerializer
JSON_s.Converters.Add(sec)

Dim jsonObject As JObject
jsonObject = JObject.FromObject(SomeObject, JSON_s)
Dim text = jsonObject.ToString

IO.File.WriteAllText(filePath, text)

0

조금 더 미래 지향적 인 옵션

동일한 질문에 직면하여 StringEnumConverter, 역 직렬화 측면에서 치명적으로 파괴하지 않고 열거 형 값이 시간이 지남에 따라 확장 될 수 있도록 사용자 정의 버전이 필요하다고 결정했습니다 (아래 배경 참조). 사용하여SafeEnumConverter 다음은 페이로드 가까이 INT - 투 - 열거 형 변환이 어떻게 작동하는지에 대한 명명 된 정의가없는 열거 값을 포함하더라도 끝까지 직렬화 할 수 있습니다.

용법:

[SafeEnumConverter]
public enum Colors
{
    Red,
    Green,
    Blue,
    Unsupported = -1
}

또는

[SafeEnumConverter((int) Colors.Blue)]
public enum Colors
{
    Red,
    Green,
    Blue
}

출처:

public class SafeEnumConverter : StringEnumConverter
{
    private readonly int _defaultValue;

    public SafeEnumConverter()
    {
        // if you've been careful to *always* create enums with `0` reserved
        // as an unknown/default value (which you should), you could use 0 here. 
        _defaultValue = -1;
    }

    public SafeEnumConverter(int defaultValue)
    {
        _defaultValue = defaultValue;
    }

    /// <summary>
    /// Reads the provided JSON and attempts to convert using StringEnumConverter. If that fails set the value to the default value.
    /// </summary>
    /// <returns>The deserialized value of the enum if it exists or the default value if it does not.</returns>
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }
        catch
        {
            return Enum.Parse(objectType, $"{_defaultValue}");
        }
    }

    public override bool CanConvert(Type objectType)
    {
        return base.CanConvert(objectType) && objectType.GetTypeInfo().IsEnum;
    }
}

배경

의 사용을 살펴봤을 때 StringEnumConverter, 우리가 가진 문제는 새로운 열거 형 값이 추가 된 경우에도 수동성이 필요하지만 모든 클라이언트가 새로운 값을 즉시 인식하지는 않았다는 것입니다. 이 경우 StringEnumConverterNewtonsoft JSON으로 패키지 된 경우 JsonSerializationException"SomeString 값을 EnumType 유형으로 변환하는 중 오류 발생"과 유사한 메시지가 표시되고 전체 역 직렬화 프로세스가 실패합니다. 클라이언트가 이해하지 못하는 속성 값을 무시 / 삭제하려고 계획 했더라도 여전히 나머지 페이로드를 역 직렬화 할 수 있어야했기 때문에 이것은 우리를위한 거래 차단기였습니다.


-2
        Person p = new Person();
        p.Age = 35;
        p.Gender = Gender.Male;
        //1.  male="Male";
        string male = Gender.Male.ToString();

        p.Gender = Gender.Female;

        //2.  female="Female";
        string female = Enum.GetName(typeof(Gender), p.Gender);

        JObject jobj = new JObject();
        jobj["Age"] = p.Age;
        jobj["Gender"] = male;
        jobj["Gender2"] = female;

        //you result:  josn= {"Age": 35,"Gender": "Male","Gender2": "Female"}
        string json = jobj.ToString();

-5
new JavaScriptSerializer().Serialize(  
    (from p   
    in (new List<Person>() {  
        new Person()  
        {  
            Age = 35,  
            Gender = Gender.Male  
        }  
    })  
    select new { Age =p.Age, Gender=p.Gender.ToString() }  
    ).ToArray()[0]  
);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.