C# 无法使用 Json.NET 将枚举正确转换为 json

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19767863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:50:07  来源:igfitidea点击:

Can't get enum to convert to json properly using Json.NET

c#json.net

提问by Xaniff

I have an enum:

我有一个枚举:

public enum Animal 
{ 
    Dog, 
    Cat, 
    BlackBear 
}

I need to send it to a third-party API. This API requires that the enum values I send be lower case and occasionally require underscores. In general, the names they require don't match the enum naming convention I use.

我需要将它发送到第三方 API。这个 API 要求我发送的枚举值是小写的,偶尔需要下划线。通常,它们需要的名称与我使用的枚举命名约定不匹配。

Using the example provided at https://gooddevbaddev.wordpress.com/2013/08/26/deserializing-c-enums-using-json-net/, I tried to use a custom JsonConverter:

使用https://gooddevbaddev.wordpress.com/2013/08/26/deserializing-c-enums-using-json-net/提供的示例,我尝试使用自定义 JsonConverter:

public class AnimalConverter : JsonConverter {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        var animal = (Animal)value;
        switch (animal)
        {
            case Animal.Dog:
            {
                writer.WriteValue("dog");
                break;
            }
            case Animal.Cat:
            {
                writer.WriteValue("cat");
                break;
            }
            case Animal.BlackBear:
            {
                writer.WriteValue("black_bear");
                break;
            }
        }
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        var enumString = (string)reader.Value;
        Animal? animal = null;
        switch (enumString)
        {
            case "cat":
            {
                animal = Animal.Cat;
                break;
            }
            case "dog":
            {
                animal = Animal.Dog;
                break;
            }
            case "black_bear":
            {
                animal = Animal.BlackBear;
                break;
            }
        }
    }

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

Back in the properties of a class, I put the attributes on the Animal as so:

回到类的属性中,我将属性放在 Animal 上,如下所示:

[JsonProperty("animal")]
[JsonConverter(typeof(AnimalConverter))]
public Animal ZooAnimals { get; set; }

When I run the program though, it seems to completely ignore the JsonConverter and rather than seeing expected values like "black_bear" or "dog", I see "BlackBear" and "Dog". How can I get the JsonConverter to actually do the conversion from the name of the enum value to the string I specify to replace that value with?

但是,当我运行该程序时,它似乎完全忽略了 JsonConverter,而不是看到“black_bear”或“dog”之类的预期值,而是看到“BlackBear”和“Dog”。如何让 JsonConverter 实际执行从枚举值的名称到我指定替换该值的字符串的转换?

Thanks!

谢谢!

采纳答案by Tim S.

You don't need to write your own converter. Json.NET's StringEnumConverterwill read the EnumMemberattribute. If you change your enumto this, it will serialize from and to the values you want.

您无需编写自己的转换器。Json.NETStringEnumConverter将读取该EnumMember属性。如果您将您的更改enum为 this,它将从您想要的值序列化和序列化到您想要的值。

[JsonConverter(typeof(StringEnumConverter))]
public enum Animals 
{
    [EnumMember(Value = "dog")]
    Dog, 
    [EnumMember(Value = "cat")]
    Cat, 
    [EnumMember(Value = "black_bear")]
    BlackBear 
}

(As a minor note, since Animalsisn't a flags enum, it should be singular: Animal. You should consider changing it to this.)

(作为一个小提示,由于Animals不是标志枚举,它应该是单数: Animal。您应该考虑将其更改为此。)

回答by 111WARLOCK111

// Might return null, better to use try catch
public static Animals GetEnum(string val)
{
    return (Animals)Enum.Parse(typeof(Animals), val, true);
}

public static string GetName(Animals an)
{
    return Enum.GetName(typeof(Animals), an);
}

public static string GetReplace(Animals an)
{
    var get = GetName(an);
    var tempstr = "";
    int getch = 0;
    foreach (var chr in get.ToCharArray())
    {
        if (chr == chr.ToUpper())
        {
            getch++;
            // Second up value char
            if (getch == 2)
            {
                tempstr += "_" + chr;
            }
            else
            {
                tempstr += chr;
            }
        }
        else
        {
             tempstr += chr;
        }
    }
    return tempstr;
}

回答by Reda

I think your ConConvert()implementation is not correct. It should be:

我认为您的ConConvert()实施不正确。它应该是:

public override bool CanConvert(Type objectType)
{
    return objectType == typeof(Animals);
}