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

C# 在Json.Net中,当字符串以数字开头时,如何处理从字符串到枚举的转换,c#,json,json.net,C#,Json,Json.net,我从服务器接收json,并使用json.Net将其转换为对象。对于一个成员,我使用的是StringEnumConverter,它工作得非常完美 但是,服务器突然决定使用字符串,该字符串也可以以数字开头,这会导致JsonSerilizationException,这显然是因为枚举不能以.Net中的数字开头 现在,我正试图找到一个解决方案来处理这个问题。我的第一个方法是在读取Json时添加一个“uu”(这样代码中的枚举在后面跟一个数字时会有一个起始u),在编写Json时,我会删除起始uu(如果后面跟

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

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

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


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

一个简单的策略是将值反序列化为
字符串
属性,然后通过访问器方法或辅助getter only属性转换为您自己的数据类型(enum或其他)。您可以创建一个
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; }
}
公共类Json_34159840
{
公共静态字符串JsonStr=@“{”“enum”“:”“1Value”“name”“:”“James”“enum2”“:”“1”“}”;
公共静态void ParseJson()
{
JsonConvert.DefaultSettings=()=>新的JsonSerializerSettings
{
转换器=新列表{new EnumConverter()}
};
//后来。。。
var result=JsonConvert.DeserializeObject(JsonStr);
Console.WriteLine(result.Enum);
Console.WriteLine(result.Enum2);
Console.WriteLine(result.Name);
}
}
公共类EnumConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
var str=value.ToString();
if(Regex.IsMatch(str,@“^”))
{
WriteValue(str.Substring(1));
}
其他的
{
WriteValue(str);
}
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var value=reader.value.ToString();
if(Regex.IsMatch(值@“^\d+$”)
{
返回Enum.Parse(objectType,value);
}
if(Regex.IsMatch(值@“^\d+”)
{
value=“\”+值;
}
返回Enum.Parse(objectType,value);
}
公共覆盖布尔CanConvert(类型objectType)
{
//您可能需要执行更具体的检查,如
//返回objectType==typeof(JsonEnum);
返回objectType.IsEnum;
}
}
公共枚举
{
_0默认值,
_1价值
}
公共类JsonClass
{
公共字符串名称{get;set;}
公共JsonEnum枚举{get;set;}
公共JSONENUM2{get;set;}
}
希望这有帮助


EDIT:增加了对整数的支持:D

您能否给出一些枚举示例以及您在jsonsomething中收到的值,如“2SomeEnum”->\u 2SomeEnum。第一个是Json中的实际值,第二个是我试图从中获取的实际枚举。是的,如果我找不到更优雅的方法,这就是解决方案。我希望使用Json.Net管道来实现这一点(也用于学习目的)哇,我现在无法验证这个解决方案,因为我正在路上,但这看起来很有意义。实际上,我不想去掉开头的数字,我实际上想在开头添加一些东西,使其成为有效的
枚举(f.e.“u”),但这是不需要动脑筋的。唯一缺少的是WriteJson,因为我需要写回正确的值(这就是为什么我不能只删除数字)。我只是想知道为什么这种方法比Json.Net中的
StringEnumConverter
构建简单得多(不那么复杂)。不知道为什么它更简单,但它确实有效。我将更新它以保留数字:)似乎正则表达式根本不匹配,因此现在它总是为每个枚举添加一个“ux”。如果它们发送的值是整数,则它将匹配正则表达式,这对于枚举是有效的json。请看我的示例,其中enum2是“1”。它会稍微慢一点,因为您知道您只想匹配数字或下划线,这就是我们真正关心的,然后匹配它。