programing

JavaScriptSerializer - 열거를 문자열로 JSON 직렬화

batch 2023. 4. 6. 21:21
반응형

JavaScriptSerializer - 열거를 문자열로 JSON 직렬화

는 수업 에 제음음음음음음음음음음음 an가 포함되어 있습니다.enum를 사용하여 할 때JavaScriptSerializer.my json result는 열거형의 을 포함하고 있습니다.string"이름"을 클릭합니다. a a a a a a a a a a a a a로 얻는 방법이 요?string할 수 .JavaScriptConverter 내가 '를 수 enum" " " 의의는: 。

예를 들어 다음과 같습니다.

enum Gender { Male, Female }

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

원하는 JSON 결과:

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

빌트인에서 이상적인 답변을 찾고 있습니다.NET 프레임워크클래스(가능하지 않은 경우, Json.net 등)는 환영입니다.

는 그 Json을 찾았다.NET은, 이 필요로 하는 것과 같은 기능을 제공합니다.StringEnumConverter★★★★

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

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

상세한 것에 대하여는, 을 참조해 주세요.

이 컨버터를 보다 글로벌하게 설정할 수 있는 장소는 다음과 같습니다.

  • 열거를 항상 문자열로 직렬화/비직렬화하려면 enum 자체를 지정합니다.

    [JsonConverter(typeof(StringEnumConverter))]  
    enum Gender { Male, Female }
    
  • 속성 장식을 피하고 싶은 경우 변환기를 JsonSerializer(Björn Egil에서 제안)에 추가할 수 있습니다.

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

    (트래비스가 추천한) 연재 중에 표시되는 모든 열거에 대해 작동합니다.

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

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

또한 StringEnumConverter(NamingStrategy, Boolean) 컨스트럭터를 사용하여 대소문자 및 번호 허용 여부를 제어할 수 있습니다.

아니요, 사용할 수 있는 특별한 속성은 없습니다. JavaScriptSerializerenums이치노은, 「」를 , 「」라고 하는 시리얼라이제이션」을 .enum숫자 값 대신 이름으로 지정합니다.


JSON을 사용할 수 있다면.「」이 아닌 「」JavaScriptSerializerOmer Bokhari가 제공한 이 질문에 대한 답변을 참조하십시오.JSON.net은 이 사용 사례를 다룹니다(속성 사용).[JsonConverter(typeof(StringEnumConverter))].net 시리얼라이저에 의해 처리되지 않는 기타 많은 것.다음은 시리얼라이저의 특징과 기능을 비교하는 링크입니다.

c# enum을 문자열로 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());

@Iggy answer는 c# enum의 JSON 시리얼화를 ASP만의 문자열로 설정합니다.NET(Web 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.실행시간시리얼화Enum Member(엔럼 멤버)

Atribute는 다음과 같습니다.

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

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

(@ob.)의 상위 답변처럼 소스 모델을 변경할 수 없었고, @Igy처럼 글로벌하게 등록하고 싶지도 않았습니다.그래서 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()
        }
    })

.net core 3 에서는, 이것은 시스템에 짜넣어진 클래스에서 가능하게 되었습니다.Text.Json(편집: 시스템Text.Json은 .net core 2.0 및 .net framework 4.7.2 이후 버전의 NuGet 패키지로도 사용할 수 있습니다.)

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; }

enum을 항상 문자열로 변환하려면 속성을 enum 자체에 배치합니다.

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

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; }
}

ASP.NET 핵심 방식:

public class Startup
{
  public IServiceProvider ConfigureServices(IServiceCollection services)
  {
    services.AddMvc().AddJsonOptions(options =>
    {
      options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
    });
  }
}

https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e

이것은, Atribute를 Etribute에 추가하는 것으로 간단하게 실시할 수 있습니다.Gender 않게 「」, 「」, 「」를합니다.GenderString시리얼화 되는 속성:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

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

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; 
        }
    }
}

여기 Newtonsoft.json에 대한 답이 있습니다.

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

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

ASP.Net Core 3 with System.Text.Json

public void ConfigureServices(IServiceCollection services)
{

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

    //...
 }

의 변환기에 추가할 수도 있습니다.JsonSerializerJsonConverter★★★★

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

은 모든 사람에게 가 있을 것이다.enum그 시리얼화중에 표시됩니다.

# 을 하고 그 C# JSON을 .<select> 에넘 사용할 수 .enum

했습니다.는 C#가 이 하여 JSON을 채울 수 입니다.이는 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"}
]

클라이언트 측 - Coffee Script

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>

ASP의 경우.Net core 스타트업 클래스에 다음 항목을 추가합니다.

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

빌트인을 사용하는 경우 .NET 6.0의 경우JsonSerializerJson)

바로만 쓰면 요. 이치노JsonStringEnumConverter를 들면 다음과 같습니다예를 들어 다음과 같습니다.

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

꼭하세요.SomeEnumType에는 정확한 문자열 값이 포함되어 있습니다.그렇지 않으면 예외가 발생합니다.케이싱은 무신경한 것 같아요

참고 자료: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-customize-properties?pivots=dotnet-6-0#enums-as-strings

JsonSerializerSettings는 JsonConverter 호출로 작성할 수 있습니다.Serialize Object는 다음과 같습니다.

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

Description Atribute가 있는 경우 시리얼라이제이션에 대한 응답이 없음을 알 수 있습니다.

다음은 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; }

.Net Core의 경우:-

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

사용방법:

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

[Serializable]
[JsonConverter(typeof(StringEnumConverter))]
public enum Gender { Male, Female }

만약 누군가가 위 내용이 불충분하다고 생각했을 경우를 대비해서, 저는 이 과부하로 해결했습니다.

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

오래된 질문이지만 만약을 위해 제가 기고해야겠다고 생각했습니다.프로젝트에서는 Json의 요청에 따라 별도의 모델을 사용합니다.모델은 일반적으로 도메인 개체와 이름이 같고 접두사가 "Json"입니다.모델은 AutoMapper를 사용하여 매핑됩니다.json 모델이 도메인 클래스의 열거형 문자열 속성을 선언하도록 하면 AutoMapper는 해당 문자열 표시로 해결됩니다.

만약 궁금하다면 Json serializer에 내장된 serializer에는 순환 참조가 있기 때문에 Json serializer 클래스용으로 별도의 모델이 필요합니다.

이게 도움이 됐으면 좋겠네요.

실제로 JavaScriptConverter를 사용하여 내장된 JavaScriptSerializer를 사용하여 이를 수행할 수 있습니다.열거형을 URI로 변환하면 문자열로 인코딩할 수 있습니다.

데이트에 대해서는 어떻게 하는지 설명했지만, 에넘에도 사용할 수 있습니다.의 커스텀 DateTime JSON 형식.NET JavaScript Serializer.

조금 더 미래 지향적인 옵션

하다고 판단했습니다.StringEnumConverter열거값이 역직렬화 측면에서 치명적으로 중단되지 않고 시간이 지남에 따라 확장될 수 있도록 합니다(아래 배경 참조).「 」의 SafeEnumConverter다음에서는 payload에 이름 있는 정의가 없는 열거형 값이 포함되어 있는 경우에도 int-to-enum 변환의 동작에 가까운 역직렬화를 완료할 수 있습니다.

사용방법:

[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문제는 새로운 열거값이 추가된 경우에도 수동성이 필요했지만 모든 클라이언트가 새로운 값을 즉시 인식하지는 않았다는 것입니다. 「」는,StringEnumConverter된 Newtonsoft JSON은 Newtonsoft JSON을 .JsonSerializationException"SomeString 값을 EnumType으로 변환하는 중 오류 발생"과 유사한 경우 전체 역직렬화 프로세스가 실패합니다.고객이 이해하지 못한 자산 가치를 무시/폐기할 계획이라도 나머지 페이로드를 역직렬화할 수 있어야 했기 때문입니다.

이것이 여전히 관련이 있는지는 모르겠지만, 저는 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 키가 json "규칙"에 따라 시작하는 소문자로 표시됩니다.완전히 들여쓰기된 형식을 지정하고 출력의 늘을 무시합니다.StringEnumConverter를 추가하면 문자열 값이 포함된 enum이 출력됩니다.

개인적으로 저는 이것이 제가 생각해낼 수 있는 가장 깔끔한 방법이라고 생각합니다.주석으로 모델을 더럽힐 필요는 없습니다.

사용방법:

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

그리고 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)

이 용액의 을 이 용액을 했습니다.Newtonsoft.Json도서관.열거형 문제를 수정하고 오류 처리도 훨씬 개선하며 IIS 호스트 서비스에서 작동합니다.꽤 많은 코드이기 때문에 GitHub에서 찾을 수 있습니다.https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs

하다에는 몇 .Web.config이 기능을 이용하려면 , 다음의 샘플 파일을 참조해 주세요.https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config

22년 5월에 솔루션을 필요로 하는 분들을 위한 것입니다.NET 6에서도 Newtonsoft를 사용하여 다음과 같이 컨버터를 글로벌하게 등록할 수 있습니다.

var builder = WebApplication.CreateBuilder(args);
...
builder.Services.AddControllers(options => options.RespectBrowserAcceptHeader = true)
.AddNewtonsoftJson(opt =>
{
    opt.SerializerSettings.ContractResolver = new DefaultContractResolver();
    opt.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
})
.AddXmlSerializerFormatters()
.AddXmlDataContractSerializerFormatters();

네임스페이스 시스템.텍스트, Json.시리얼라이제이션에는 다음과 같이 사용할 수 있는JsonStringEnumConverter가 있습니다.[Json Converter (type of (Json String Enum Converter)]

        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();

언급URL : https://stackoverflow.com/questions/2441290/javascriptserializer-json-serialization-of-enum-as-string

반응형