<bdo id='fDo2k'></bdo><ul id='fDo2k'></ul>
<tfoot id='fDo2k'></tfoot>

    <small id='fDo2k'></small><noframes id='fDo2k'>

    <i id='fDo2k'><tr id='fDo2k'><dt id='fDo2k'><q id='fDo2k'><span id='fDo2k'><b id='fDo2k'><form id='fDo2k'><ins id='fDo2k'></ins><ul id='fDo2k'></ul><sub id='fDo2k'></sub></form><legend id='fDo2k'></legend><bdo id='fDo2k'><pre id='fDo2k'><center id='fDo2k'></center></pre></bdo></b><th id='fDo2k'></th></span></q></dt></tr></i><div id='fDo2k'><tfoot id='fDo2k'></tfoot><dl id='fDo2k'><fieldset id='fDo2k'></fieldset></dl></div>

    1. <legend id='fDo2k'><style id='fDo2k'><dir id='fDo2k'><q id='fDo2k'></q></dir></style></legend>

    2. 如何在 json 反序列化期间忽略未知的枚举值?

      时间:2023-08-23
      <i id='XqBx4'><tr id='XqBx4'><dt id='XqBx4'><q id='XqBx4'><span id='XqBx4'><b id='XqBx4'><form id='XqBx4'><ins id='XqBx4'></ins><ul id='XqBx4'></ul><sub id='XqBx4'></sub></form><legend id='XqBx4'></legend><bdo id='XqBx4'><pre id='XqBx4'><center id='XqBx4'></center></pre></bdo></b><th id='XqBx4'></th></span></q></dt></tr></i><div id='XqBx4'><tfoot id='XqBx4'></tfoot><dl id='XqBx4'><fieldset id='XqBx4'></fieldset></dl></div>

        • <legend id='XqBx4'><style id='XqBx4'><dir id='XqBx4'><q id='XqBx4'></q></dir></style></legend>
            <bdo id='XqBx4'></bdo><ul id='XqBx4'></ul>
              <tbody id='XqBx4'></tbody>

            <tfoot id='XqBx4'></tfoot>

              • <small id='XqBx4'></small><noframes id='XqBx4'>

              • 本文介绍了如何在 json 反序列化期间忽略未知的枚举值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                当我的枚举与 json 属性中提供的字符串值不匹配时,如何让 Json.net 不出错?

                How can I get Json.net not to throw up when my enum doesn't match string value provided in the json property?

                当我根据当前文档创建枚举时会发生这种情况,但第三方 API 稍后会添加更多枚举值.

                This happens when I create enum based on current documentation, but the third party API adds more enum values later.

                我很乐意将特殊值标记为 Unknown 或使用可为空的枚举,不匹配的值将返回 null.

                I would be happy with either marking special value as Unknown or using a nullable enum and unmatched value would return null.

                推荐答案

                您可以使用自定义 JsonConverter 解决此问题.这是我使用来自 Json.Net 的 StringEnumConverter 类中的几部分组合而成的.它应该使您可以灵活地处理任何您决定的事情.以下是它的工作原理:

                You can solve this problem with a custom JsonConverter. Here is one I put together using a few pieces from the StringEnumConverter class that comes from Json.Net. It should give you the flexibility to handle things whatever way you decide. Here's how it works:

                • 如果在 JSON 中找到的值与枚举匹配(作为字符串或整数),则使用该值.(如果值为整数并且有多个可能的匹配项,则使用其中的第一个.)
                • 否则,如果枚举类型可以为空,则将值设置为空.
                • 否则,如果枚举具有称为未知"的值,则使用该值.
                • 否则使用枚举的第一个值.

                这里是代码.随意更改它以满足您的需求.

                Here is the code. Feel free to change it to meet your needs.

                class TolerantEnumConverter : JsonConverter
                {
                    public override bool CanConvert(Type objectType)
                    {
                        Type type = IsNullableType(objectType) ? Nullable.GetUnderlyingType(objectType) : objectType;
                        return type.IsEnum;
                    }
                
                    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
                    {
                        bool isNullable = IsNullableType(objectType);
                        Type enumType = isNullable ? Nullable.GetUnderlyingType(objectType) : objectType;
                
                        string[] names = Enum.GetNames(enumType);
                
                        if (reader.TokenType == JsonToken.String)
                        {
                            string enumText = reader.Value.ToString();
                
                            if (!string.IsNullOrEmpty(enumText))
                            {
                                string match = names
                                    .Where(n => string.Equals(n, enumText, StringComparison.OrdinalIgnoreCase))
                                    .FirstOrDefault();
                
                                if (match != null)
                                {
                                    return Enum.Parse(enumType, match);
                                }
                            }
                        }
                        else if (reader.TokenType == JsonToken.Integer)
                        {
                            int enumVal = Convert.ToInt32(reader.Value);
                            int[] values = (int[])Enum.GetValues(enumType);
                            if (values.Contains(enumVal))
                            {
                                return Enum.Parse(enumType, enumVal.ToString());
                            }
                        }
                
                        if (!isNullable)
                        {
                            string defaultName = names
                                .Where(n => string.Equals(n, "Unknown", StringComparison.OrdinalIgnoreCase))
                                .FirstOrDefault();
                
                            if (defaultName == null)
                            {
                                defaultName = names.First();
                            }
                
                            return Enum.Parse(enumType, defaultName);
                        }
                
                        return null;
                    }
                
                    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
                    {
                        writer.WriteValue(value.ToString());
                    }
                
                    private bool IsNullableType(Type t)
                    {
                        return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
                    }
                }
                

                这是一个演示,它使用几个不同的枚举(一个具有未知"值,而另一个没有)使转换器完成其步调:

                Here is a demo which puts it the converter through its paces using a couple of different enums (one has an "Unknown" value, and the other does not):

                [JsonConverter(typeof(TolerantEnumConverter))]
                enum Status
                {
                    Ready = 1,
                    Set = 2,
                    Go = 3
                }
                
                [JsonConverter(typeof(TolerantEnumConverter))]
                enum Color
                {
                    Red = 1,
                    Yellow = 2,
                    Green = 3,
                    Unknown = 99
                }
                
                class Foo
                {
                    public Status NonNullableStatusWithValidStringValue { get; set; }
                    public Status NonNullableStatusWithValidIntValue { get; set; }
                    public Status NonNullableStatusWithInvalidStringValue { get; set; }
                    public Status NonNullableStatusWithInvalidIntValue { get; set; }
                    public Status NonNullableStatusWithNullValue { get; set; }
                
                    public Status? NullableStatusWithValidStringValue { get; set; }
                    public Status? NullableStatusWithValidIntValue { get; set; }
                    public Status? NullableStatusWithInvalidStringValue { get; set; }
                    public Status? NullableStatusWithInvalidIntValue { get; set; }
                    public Status? NullableStatusWithNullValue { get; set; }
                
                    public Color NonNullableColorWithValidStringValue { get; set; }
                    public Color NonNullableColorWithValidIntValue { get; set; }
                    public Color NonNullableColorWithInvalidStringValue { get; set; }
                    public Color NonNullableColorWithInvalidIntValue { get; set; }
                    public Color NonNullableColorWithNullValue { get; set; }
                
                    public Color? NullableColorWithValidStringValue { get; set; }
                    public Color? NullableColorWithValidIntValue { get; set; }
                    public Color? NullableColorWithInvalidStringValue { get; set; }
                    public Color? NullableColorWithInvalidIntValue { get; set; }
                    public Color? NullableColorWithNullValue { get; set; }
                }
                
                class Program
                {
                    static void Main(string[] args)
                    {
                        string json = @"
                        {
                            ""NonNullableStatusWithValidStringValue"" : ""Set"",
                            ""NonNullableStatusWithValidIntValue"" : 2,
                            ""NonNullableStatusWithInvalidStringValue"" : ""Blah"",
                            ""NonNullableStatusWithInvalidIntValue"" : 9,
                            ""NonNullableStatusWithNullValue"" : null,
                            ""NullableStatusWithValidStringValue"" : ""Go"",
                            ""NullableStatusWithValidIntValue"" : 3,
                            ""NullableStatusWithNullValue"" : null,
                            ""NullableStatusWithInvalidStringValue"" : ""Blah"",
                            ""NullableStatusWithInvalidIntValue"" : 9,
                            ""NonNullableColorWithValidStringValue"" : ""Green"",
                            ""NonNullableColorWithValidIntValue"" : 3,
                            ""NonNullableColorWithInvalidStringValue"" : ""Blah"",
                            ""NonNullableColorWithInvalidIntValue"" : 0,
                            ""NonNullableColorWithNullValue"" : null,
                            ""NullableColorWithValidStringValue"" : ""Yellow"",
                            ""NullableColorWithValidIntValue"" : 2,
                            ""NullableColorWithNullValue"" : null,
                            ""NullableColorWithInvalidStringValue"" : ""Blah"",
                            ""NullableColorWithInvalidIntValue"" : 0,
                        }";
                
                        Foo foo = JsonConvert.DeserializeObject<Foo>(json);
                        foreach (PropertyInfo prop in typeof(Foo).GetProperties())
                        {
                            object val = prop.GetValue(foo, null);
                            Console.WriteLine(prop.Name + ": " + 
                                             (val == null ? "(null)" : val.ToString()));
                        }
                    }
                }
                

                输出:

                NonNullableStatusWithValidStringValue: Set
                NonNullableStatusWithValidIntValue: Set
                NonNullableStatusWithInvalidStringValue: Ready
                NonNullableStatusWithInvalidIntValue: Ready
                NonNullableStatusWithNullValue: Ready
                NullableStatusWithValidStringValue: Go
                NullableStatusWithValidIntValue: Go
                NullableStatusWithInvalidStringValue: (null)
                NullableStatusWithInvalidIntValue: (null)
                NullableStatusWithNullValue: (null)
                NonNullableColorWithValidStringValue: Green
                NonNullableColorWithValidIntValue: Green
                NonNullableColorWithInvalidStringValue: Unknown
                NonNullableColorWithInvalidIntValue: Unknown
                NonNullableColorWithNullValue: Unknown
                NullableColorWithValidStringValue: Yellow
                NullableColorWithValidIntValue: Yellow
                NullableColorWithInvalidStringValue: (null)
                NullableColorWithInvalidIntValue: (null)
                NullableColorWithNullValue: (null)
                

                这篇关于如何在 json 反序列化期间忽略未知的枚举值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:无法将当前 JSON 对象(例如 {“name":“value&qu 下一篇:“检测到自参考循环"JSON.Net 例外

                相关文章

                最新文章

                <tfoot id='5JNOX'></tfoot>
                    <i id='5JNOX'><tr id='5JNOX'><dt id='5JNOX'><q id='5JNOX'><span id='5JNOX'><b id='5JNOX'><form id='5JNOX'><ins id='5JNOX'></ins><ul id='5JNOX'></ul><sub id='5JNOX'></sub></form><legend id='5JNOX'></legend><bdo id='5JNOX'><pre id='5JNOX'><center id='5JNOX'></center></pre></bdo></b><th id='5JNOX'></th></span></q></dt></tr></i><div id='5JNOX'><tfoot id='5JNOX'></tfoot><dl id='5JNOX'><fieldset id='5JNOX'></fieldset></dl></div>
                  1. <small id='5JNOX'></small><noframes id='5JNOX'>

                    <legend id='5JNOX'><style id='5JNOX'><dir id='5JNOX'><q id='5JNOX'></q></dir></style></legend>
                    • <bdo id='5JNOX'></bdo><ul id='5JNOX'></ul>