programing

json 문자를 열거형으로 역직렬화

javamemo 2023. 3. 6. 20:37
반응형

json 문자를 열거형으로 역직렬화

C#으로 정의된 열거형이 있으며, 여기서 값을 다음과 같이 문자로 저장합니다.

public enum CardType
{
    Artist = 'A',
    Contemporary = 'C',
    Historical = 'H',
    Musician = 'M',
    Sports = 'S',
    Writer = 'W'
}

JSON을 사용하여 역직렬화를 시도합니다.NET 단, 착신 JSON은 다음과 같이 열거의 int 값이 아닌 CHAR 값(문자열)을 사용하여 작성되었습니다.

[{"CardType","A"},{"CardType", "C"}]

char를 수동으로 enum 값으로 해석할 수 있는 변환기를 정의할 수 있습니까?

JsonConverter를 작성하려고 했는데, 이 속성에만 적용하면서 구문 분석된 개체 전체에는 적용되지 않고 어떻게 작성해야 하는지 잘 모르겠습니다.제가 시도한 것은 다음과 같습니다.

public class EnumerationConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
        {
            return null;
        }

        int value = serializer.Deserialize<int>(reader);
        return (CardType)value;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsSubclassOf(typeof(string));
    }
}

논리가 틀릴 수도 있고 수정할 수도 있지만 ReadJson()이 전혀 호출되지 않는 것이 문제입니다.

CanConvert는 다음과 같이 정의되어 있는1개의 속성뿐만 아니라 모든 속성에도 호출되어 있는 것 같습니다.

public class Card
{
            private CardType type;
        [JsonConverter(typeof(EnumerationConverter))]
        public CardType Type
        {
            get { return type; }
            set { type = value; }
        }
}

잘못 실행한 것 같습니다만, 단일 필드에 대한 실행 방법에 대한 문서를 찾는 데 어려움을 겪고 있습니다.

제가 무엇을 빠뜨리고 있나요?

커스텀은 필요 없습니다.JsonConverter빌트인을 사용할 수 있습니다.StringEnumConverter(에서)를 조합하여System.Runtime.Serialization어셈블리).

미포함EnumMemberAttributeArtist, Contemporary 등의 열거형 이름을 사용하기 때문에 A, C 등의 값으로 이름을 변경해야 합니다.

그러나 값을 두 번 반복해야 하므로 가장 적합한 솔루션은 아닙니다. 하지만 다음과 같이 작동합니다.

[JsonConverter(typeof(StringEnumConverter))]
public enum CardType
{
    [EnumMember(Value = "A")]
    Artist = 'A',
    [EnumMember(Value = "C")]
    Contemporary = 'C',
    [EnumMember(Value = "H")]
    Historical = 'H',
    [EnumMember(Value = "M")]
    Musician = 'M',
    [EnumMember(Value = "S")]
    Sports = 'S',
    [EnumMember(Value = "W")]
    Writer = 'W'
}

이 코드는 완벽하게 동작합니다.

CardType[] array = { CardType.Artist, CardType.Contemporary };
string s = JsonConvert.SerializeObject(array);
var array2 = JsonConvert.DeserializeObject<CardType[]>(s);

업데이트:
바로 사용할 수 있는 제품은?StringEnumConverter:

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

Serializer Settings만 추가하면 됩니다.컨버터추가(새로운 String Enum Converter());

BrowserJsonFormatter 클래스로 이동합니다.

public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
    public BrowserJsonFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        SerializerSettings.Formatting = Formatting.Indented;
        SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
        SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        SerializerSettings.Converters.Add(new EmptyToNullConverter());
        SerializerSettings.Converters.Add(new StringEnumConverter());
        //SerializerSettings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
    }

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
    {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType = new MediaTypeHeaderValue("application/json");
    }
}

커스텀 Json Converter를 사용하는 것은 다음과 같습니다.저는 낮에는 Java 개발자이기 때문에 C#의 전문 개발자가 이를 개선하거나 문제를 발견할 수 있을 것입니다.

public class CharEnumConverter<T> : JsonConverter<T>
{
    public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
    {
        char c = (char)(int)Enum.Parse(typeof(T), value.ToString());
        writer.WriteValue(c + "");
    }

    public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        string stringValue = (string)reader.Value;
        char charValue = stringValue[0];
        int intValue = (int)charValue;
        string intValueString = intValue + "";

        if (Enum.IsDefined(typeof(T), intValue)) {
            T result = (T)Enum.Parse(typeof(T), intValueString);
            return result;
        } else {
            throw new Exception("Char value [" + charValue + "] is not defined for Enum [" + typeof(T).Name + "]");
        }
    }
}

Json으로 읽고 쓸 열거형 사용 예.

[CharEnum]    
public enum MyEnum {
    NONE = 'A',
    YAY = 'B'
}

public class MyClass {

    [JsonConverter(typeof(CharEnumConverter<MyEnum>))]    
    public MyEnum myfield;

}

JSON 문자열에서 값이 NONE인 열거형 필드로 'A'를 읽습니다.값이 YAY인 열거 필드를 JSON 문자열에 'B'로 씁니다.

언급URL : https://stackoverflow.com/questions/18551452/deserialize-json-character-as-enumeration

반응형