当字符串以 Json.Net 中的数字开头时如何处理从字符串到枚举的转换

zlZ*_*mon 5 c# json json.net

我正在从服务器接收 json,我正在使用 Json.Net 将其转换为对象。对于一个成员,我正在使用StringEnumConverter它的工作非常完美。

然而,突然间,服务器决定使用也可以以数字开头的字符串,这会导致 JsonSerilizationException - 显然是因为枚举不能以 .Net 中的数字开头。

现在我正试图找到一个解决方案来处理这个问题。我的第一种方法是在读取 Json 时添加一个“_”(所以我的代码中的枚举在后面跟一个数字时会有一个起始 _),并且在编写json 我会删除起始 _ (如果后面有数字)。为了实现这一点,我将 复制StringEnumConverter到我的命名空间中,并尝试更改WriteJsonReadJson方法中的相应部分。但是我不能使用 ,StringEnumConverter因为在我自己的命名空间中有我无法访问的其他依赖项。

这个问题有什么优雅的解决方案吗?

sQu*_*r3l 4

您可以创建一个JsonConverter并修剪前面的数字

public class Json_34159840
{
    public static string JsonStr = @"{""enum"":""1Value"",""name"":""James"",""enum2"":""1""}";

    public static void ParseJson()
    {
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> { new EnumConverter() }
        };

        // Later on...
        var result = JsonConvert.DeserializeObject<JsonClass>(JsonStr);
        Console.WriteLine(result.Enum);
        Console.WriteLine(result.Enum2);
        Console.WriteLine(result.Name);
    }
}

public class EnumConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var str = value.ToString();
        if (Regex.IsMatch(str, @"^_"))
        {
            writer.WriteValue(str.Substring(1));
        }
        else
        {
            writer.WriteValue(str);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var value = reader.Value.ToString();
        if (Regex.IsMatch(value, @"^\d+$"))
        {
            return Enum.Parse(objectType, value);
        }

        if (Regex.IsMatch(value, @"^\d+"))
        {
            value = "_" + value;
        }

        return Enum.Parse(objectType, value);
    }

    public override bool CanConvert(Type objectType)
    {
        //You might want to do a more specific check like
        //return objectType == typeof(JsonEnum);
        return objectType.IsEnum;
    }
}

public enum JsonEnum
{
    _0Default,
    _1Value
}

public class JsonClass
{
    public string Name { get; set; }
    public JsonEnum Enum { get; set; }
    public JsonEnum Enum2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

编辑:添加了对整数的支持:D