如何在.NET中处理空字符串的反序列化?

时间:2015-01-28 22:50:52

标签: c# .net serialization

下图显示了在序列化/反序列化的帮助下使用TestClass2类型的对象构建类型TestClass1的对象。

TestClass1TestClass2具有相同的结构,但其中一个成员是TestClass1中的字符串,但TestClass2中的字符串长。

public class TestClass1
{
    public string strlong;
}

public class TestClass2
{
    public long strlong;
}

TestClass1 objT1 = new TestClass1();
objT1.strlong = "20134567";
TestClass2 objT2;
JavaScriptSerializer serializer = new JavaScriptSerializer();
string JSON1 = serializer.Serialize(objT1);
objT2 = serializer.Deserialize<TestClass2>(JSON1);

操作完成后,objT2的值将为objT1,但strlong现在将为长而不是字符串。

问题是,如果strlong中的objT1值为空字符串 - >&gt; “”,反序列化失败,异常"" is not a valid value for Int64

如果strlong是非空字符串,只包含数字字符,则当前反序列化工作正常。但是当我出现像空字符串这样的东西时,我不知道解决方法。

现在,我们假设

  1. strlong将在长
  2. 范围内
  3. 只是一个数字字符序列,即它不会有.,/或任何类型的其他字符
  4. 只能访问序列化对象,我无法修改TestClass1TestClass2
  5. 如果使用另一个类的对象创建一个类的对象有一个简单的方法(或不是),请在评论中提及。

    编辑 - 扩展逻辑

    为了将下面的答案中给出的解决方案的逻辑扩展到包含其他类的成员的类,我已经使用下面给出的序列化解决方案来成员项。换句话说,如果类包含其他类的成员,是否有更好的方法来处理比下面的代码更深层次?

    // **Item1 :** 
    // These are the subclasses and classes
    // whose objects I am trying to serialize
    // and deserialize from one type to another
    public class SubClass1
    {
        public string toomuch;
        public int number = 30;
    }
    
    public class SubClass2
    {
        public long toomuch;
        public int number;
    }
    
    public class TestClass1
    {
        public string strlong;
        public SubClass1 item2;
    }
    
    public class TestClass2
    {
        public long strlong;
        public SubClass2 item2;
    }
    
    // **Item2 :** 
    // Solution from StackOverflow for serialization of 
    // empty string
    public class TestClass1Converter : JavaScriptConverter
    {
        public override IEnumerable<Type> SupportedTypes
        {
            get { return new Type[] { typeof(TestClass1) }; }
        }
    
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            var data = obj as TestClass1;
            var dic = new Dictionary<string, object>();
            if (data == null)
            {
                return dic;
            }
    
            long val = 0;
            long.TryParse(data.strlong, out val);
            dic.Add("strlong", val);
    
            // **Item3 :** 
            // trying to serialize and deserialize item2 which is of type SubClass1
            // which might also have empty string
            /*******************/
            JavaScriptSerializer subClassSerializer = new JavaScriptSerializer();
            subClassSerializer.RegisterConverters(new[] { new SubClass1Converter() });
            string JSONstr = subClassSerializer.Serialize(data.item2);
            dic.Add("item2", subClassSerializer.Deserialize<SubClass2>(JSONstr));
            /*******************/
    
            return dic;
        }
    
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    // **Item4 :** 
    // Serialization for subclass
    public class SubClass1Converter : JavaScriptConverter
    {
        public override IEnumerable<Type> SupportedTypes
        {
            get { return new Type[] { typeof(SubClass1) }; }
        }
    
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            var data = obj as SubClass1;
            var dic = new Dictionary<string, object>();
            if (data == null)
            {
                return dic;
            }
    
            long val = 0;
            long.TryParse(data.toomuch, out val);
            dic.Add("toomuch", val);
            dic.Add("number", data.number);
            return dic;
        }
    
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            TestClass1 objT1 = new TestClass1();
            objT1.strlong = "";
            SubClass1 objSub = new SubClass1();
            objSub.toomuch = "";
            objT1.item2 = objSub;
            TestClass2 objT2;
    
    
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            serializer.RegisterConverters(new[] { new TestClass1Converter() });
            string JSON1 = serializer.Serialize(objT1);
            objT2 = serializer.Deserialize<TestClass2>(JSON1);
        }
    }
    

1 个答案:

答案 0 :(得分:2)

您应该将TestClass2.strlong声明为可以为空。

public class TestClass2
{
    public long? strlong;
}

现在,如果null为空字符串或为null,则可以TestClass1.strlong

如果您无权修改课程,则更新

您应该通过RegisterConverters向转换器添加转换器以自定义转换。这是一个例子:

public class TestClass1Converter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { return new Type[] { typeof(TestClass1)}; }
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var data = obj as TestClass1;
        var dic = new Dictionary<string, object>();
        if(data == null)
        {
            return dic;
        }

        long val = 0;
        long.TryParse(data.strlong, out val);
        dic.Add("strlong", val);
        return dic;
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

如果转换器无法转换为strlong,此转换器会将long序列化为0。您可以这样使用它:

TestClass1 objT1 = new TestClass1();
objT1.strlong = "444";
TestClass2 objT2;
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new [] {new TestClass1Converter()});
string JSON1 = serializer.Serialize(objT1);
objT2 = serializer.Deserialize<TestClass2>(JSON1);