如何在 .NET 中将空字符串反序列化为 long?
How to handle deserialization of empty string into long in .NET?
下图表示在 Serialization/Deserialization.
的帮助下使用 TestClass1
类型的对象构建 TestClass2
类型的对象
TestClass1
和 TestClass2
具有相同的结构,只是其中一个成员在 TestClass1
中是 string 而在 TestClass2
中是 long。
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
现在将是长而不是字符串。
问题是,如果 objT1
中的 strlong
值为空字符串 --> "",反序列化失败并出现异常 "" is not a valid value for Int64
。
如果 strlong
是仅包含数字字符的非空字符串,则当前反序列化有效。但是当出现空字符串之类的东西时,我不知道解决方法。
现在,让我们假设
strlong
将在 long 的范围内
- 将只是一个数字字符序列,即它不会有
.
或 ,
或 /
或任何类型的其他字符
- 只能访问用于序列化的对象,我无法修改
TestClass1
或 TestClass2
。
如果有一种简单的方法(或没有)使用另一个 class 的对象创建一个 class 的对象,请在评论中提及。
编辑-扩展逻辑
为了将下面的答案中给出的解决方案逻辑扩展到 类 包含类型为其他 class 的成员,我也对成员项目使用了下面给出的序列化解决方案。换句话说,如果 classes 包含其他 classes 的成员,是否有比下面的代码更好的处理更深层次的方法?
// **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 Whosebug 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);
}
}
您应该将 TestClass2.strlong
声明为可为空。
public class TestClass2
{
public long? strlong;
}
现在您可以使用 null
以防 TestClass1.strlong
为空字符串或 null。
这是 UPDATE,以防您无法修改 类。
您应该通过 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
序列化为 0,以防无法转换为 long
。你可以这样使用它:
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);
下图表示在 Serialization/Deserialization.
的帮助下使用TestClass1
类型的对象构建 TestClass2
类型的对象
TestClass1
和 TestClass2
具有相同的结构,只是其中一个成员在 TestClass1
中是 string 而在 TestClass2
中是 long。
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
现在将是长而不是字符串。
问题是,如果 objT1
中的 strlong
值为空字符串 --> "",反序列化失败并出现异常 "" is not a valid value for Int64
。
如果 strlong
是仅包含数字字符的非空字符串,则当前反序列化有效。但是当出现空字符串之类的东西时,我不知道解决方法。
现在,让我们假设
strlong
将在 long 的范围内
- 将只是一个数字字符序列,即它不会有
.
或,
或/
或任何类型的其他字符 - 只能访问用于序列化的对象,我无法修改
TestClass1
或TestClass2
。
如果有一种简单的方法(或没有)使用另一个 class 的对象创建一个 class 的对象,请在评论中提及。
编辑-扩展逻辑
为了将下面的答案中给出的解决方案逻辑扩展到 类 包含类型为其他 class 的成员,我也对成员项目使用了下面给出的序列化解决方案。换句话说,如果 classes 包含其他 classes 的成员,是否有比下面的代码更好的处理更深层次的方法?
// **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 Whosebug 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);
}
}
您应该将 TestClass2.strlong
声明为可为空。
public class TestClass2
{
public long? strlong;
}
现在您可以使用 null
以防 TestClass1.strlong
为空字符串或 null。
这是 UPDATE,以防您无法修改 类。
您应该通过 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
序列化为 0,以防无法转换为 long
。你可以这样使用它:
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);