【问题标题】:JavaScriptSerializer.Deserialize() skip property if cannot parse itJavaScriptSerializer.Deserialize() 如果无法解析则跳过属性
【发布时间】:2013-08-19 17:20:45
【问题描述】:

我正在使用此代码将 JSON 字符串反序列化为使用 Person 对象:

JavaScriptSerializer serializer = new JavaScriptSerializer();
Person person = serializer.Deserialize<Person>(jsonString);

Person 类有一个 Age 属性:

int Age {get;set;}

JSON 字符串的值如下:

{age: '无效的 int'}

我收到如下异常:

无法将字符串转换为 Int32

有什么方法可以告诉JavaScriptSerializer 跳过错误并继续处理其他属性?

【问题讨论】:

    标签: c# .net json javascriptserializer


    【解决方案1】:

    是的,可以通过编写自定义JavaScriptConverter类来控制反序列化过程:

    public class PersonConverter : JavaScriptConverter
    {
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            Person person = new Person();
    
            foreach (string key in dictionary.Keys)
            {
                var value = dictionary[key];
    
                switch (key)
                {
                    case "Name":
                        person.Name = (string)value;
                        break;
    
                    case "Age":
                        {
                            if (value is int)
                            {
                                person.Age = (int)value;
                            }
                            else
                            {
                                int age;
                                if (int.TryParse((string)dictionary[key], out age))
                                {
                                    person.Age = age;
                                } // else leave Age as null (or if int, leave as 0); alternatively put an else block here to set to value of your choice
                            }
                        }
                        break;
                }
            }
    
            return person;
        }
    
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override IEnumerable<Type> SupportedTypes
        {
            get
            {
                return new[] { typeof(Person) };
            }
        }
    }
    

    我冒昧地将Person.Age 设为可空,其中null 表示年龄未知,但如果这是不可接受的,您可以在年龄不可解析时将转换器修改为默认值0 或-1 :

    public class Person
    {
        public string Name { get; set; }
        public int? Age { get; set; }
    }
    

    用法:

    var serializer = new JavaScriptSerializer();
    serializer.RegisterConverters(new[] { new PersonConverter() });
    var person = serializer.Deserialize<Person>(jsonString);
    

    输出示例:

        var serializer = new JavaScriptSerializer();
        serializer.RegisterConverters(new[] { new PersonConverter() });
    
        var jsonStrings = new List<string>
        {
            "{ Name: 'Steve',  Age: 21 }",
            "{ Name: 'Teoman',  Age: 'not valid int'}",
            "{ Name: 'Queen Elizabeth II',  Age: '89'}"
        };
    
        foreach (var jsonString in jsonStrings)
        {
            var person = serializer.Deserialize<Person>(jsonString);
            Console.WriteLine("Name: {0}, Age: {1}", person.Name, person.Age);
        }
    

    姓名:史蒂夫,年龄:21

    姓名:提奥曼,年龄:

    姓名:伊丽莎白二世女王,年龄:89

    请注意,我们在这里处理的是:文字数字、字符串中的数字和完全无效的值。

    【讨论】:

      猜你喜欢
      • 2019-03-01
      • 2022-10-08
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 2013-07-25
      • 2014-02-24
      相关资源
      最近更新 更多