C# 如何序列化IEnumerable<;char>;作为字符串&;混淆反序列化错误
假设我有以下简单的类:C# 如何序列化IEnumerable<;char>;作为字符串&;混淆反序列化错误,c#,xml,serialization,C#,Xml,Serialization,假设我有以下简单的类: [XmlRoot] [XmlType("string")] public partial class eString : IEnumerable<char> { string AsString {get;set;} public IEnumerator<char> GetEnumerator() { return this.AsString.ToCharArray().ToList().GetEnumerat
[XmlRoot]
[XmlType("string")]
public partial class eString : IEnumerable<char>
{
string AsString {get;set;}
public IEnumerator<char> GetEnumerator()
{
return this.AsString.ToCharArray().ToList().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.AsString.ToCharArray().GetEnumerator();
}
public void Add(char character)
{
this.AsString += character;
}
}
[XmlRoot]
[XmlType(“字符串”)]
公共部分类限制:IEnumerable
{
字符串关联{get;set;}
公共IEnumerator GetEnumerator()
{
返回此.AsString.ToCharArray().ToList().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回此.AsString.ToCharArray().GetEnumerator();
}
公共无效添加(字符)
{
this.AsString+=字符;
}
}
还有一个namedValue类:
[XmlRoot]
public partial class eNamedValue: KeyValuePair<eString,object>
{...}
[XmlRoot]
公共部分类eNamedValue:KeyValuePair
{...}
最后
[XmlRoot]
public partial class eList<T>: List<eNamedValue>
{...}
[XmlRoot]
公共部分类eList:列表
{...}
现在,我使用以下XML序列化程序序列化eList或从eList继承的任何类:
public static XDocument Serialize<T>(this T obj) where T: new()
{
Type tt = obj.GetType();
XmlSerializer xsSubmit = new XmlSerializer(tt);
StringWriter sww = new StringWriter();
XmlWriter writer = XmlWriter.Create(sww);
xsSubmit.Serialize(writer, obj);
return XDocument.Parse(sww.ToString());
}
publicstaticxdocument序列化(这个T对象),其中T:new()
{
类型tt=obj.GetType();
XmlSerializer xsSubmit=新的XmlSerializer(tt);
StringWriter sww=新StringWriter();
XmlWriter=XmlWriter.Create(sww);
xsSubmit.Serialize(writer,obj);
返回XDocument.Parse(sww.ToString());
}
序列化可以工作-但是我的eString被序列化为字符数组,所以我没有得到“字符串”,而是得到单个字符的值:
<eNamedList>
<Key>99</Key>
<Key>111</Key>
<Key>100</Key>
<Key>101</Key>...
99
111
100
101...
此外,关于反序列化(已解决,请参阅下面的更新#1):
publicstatict反序列化(此XDocumentXML),其中T:new()
{
var serializer=newxmlserializer(typeof(T));
T结果;
使用(TextReader=newStringReader(xml.ToString()))
{
结果=(T)序列化程序。反序列化(读取器);
}
返回结果;
}
我收到以下错误:
System.Runtime.Serialization.SerializationException:第1行位置111处出错。应为命名空间“”中的元素“eNamedList”。。遇到名称为“eNamedList”、命名空间为“”的“元素”
因此,我的问题变成:
eString
或任何IEnumerable
的序列化,并始终将其序列化为字符串更新#1: 因此,我从eString中删除了
IEnumerable
接口,只保留了IEnumerable.GetEnumerator()
方法,该方法允许我的字符串在foreach循环中用作IEnumerable
,但作为字符串序列化#赢
另外,多亏了dbc,使用XML反序列化程序(而不是DataContract序列化程序)更新了原始帖子,反序列化工作正常。要回答您的问题:
[XmlRoot("string-wrapper")]
public class CustomString : IXmlSerializable
{
public string Value { get; set; }
public XmlSchema GetSchema()
{
return null; // GetSchema should not be used.
}
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
bool isEmpty = reader.IsEmptyElement;
reader.ReadStartElement();
if (!isEmpty)
{
Value = reader.ReadString();
reader.ReadEndElement();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteString(Value);
}
}
测试。我将在这篇文章的末尾发布一些测试代码
您的反序列化可能已中断,因为XmlSerializer不知道您标记为serializable的IEnumerable实际上应该被视为字符串
现在。。。忘了我刚才告诉你的吧。除非您有非常具体的格式要求,否则您不应该实现自己版本的字符串。内置的格式化程序知道更多的格式化技巧(),所以您可能应该让它完成它的工作
序列化类是属性的用武之地,尽管我建议您切换到WFC数据契约,它一开始可能听起来很吓人,但实际上用更少的代码提供了更多。再说一次,我不确定您想要完成什么,但是请相信我,您不想养成手写XML的习惯
如果您愿意,您可能会喜欢动态对象和ExpandoObject()。这些类型一起消除了所有类型,并允许您动态创建字典、数组、命名属性等等
最后,简单的泛型!反序列化泛型类不是一项简单的任务。此外,你可能不需要这样做。如果需要自己的集合,请尝试System.collections.ObjectModel命名空间。您不必担心维护列表和实现接口,只需担心实际存储的内容:
class DictionaryOfStringsAndObjects : KeyedCollection<string, object {...}
class CollectionOfStrings : Collection<string> {...}
类词典yofstringsandObjects:KeyedCollection回答您的问题:
您可能不应该用自定义字符串解决方案重新发明轮子。无论如何,如果您想要(疯狂地)对(反)序列化进行高级控制,您可以实现IXmlSerializable,并自己做完全相同的事情
[XmlRoot("string-wrapper")]
public class CustomString : IXmlSerializable
{
public string Value { get; set; }
public XmlSchema GetSchema()
{
return null; // GetSchema should not be used.
}
public void ReadXml(XmlReader reader)
{
reader.MoveToContent();
bool isEmpty = reader.IsEmptyElement;
reader.ReadStartElement();
if (!isEmpty)
{
Value = reader.ReadString();
reader.ReadEndElement();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteString(Value);
}
}
自定义字符串的序列化现在产生测试。我将在这篇文章的末尾发布一些测试代码
您的反序列化可能已中断,因为XmlSerializer不知道您标记为serializable的IEnumerable实际上应该被视为字符串
现在。。。忘了我刚才告诉你的吧。除非您有非常具体的格式要求,否则您不应该实现自己版本的字符串。内置的格式化程序知道更多的格式化技巧(),所以您可能应该让它完成它的工作
序列化类是属性的用武之地,尽管我建议您切换到WFC数据契约,它一开始可能听起来很吓人,但实际上用更少的代码提供了更多。再说一次,我不确定您想要完成什么,但是请相信我,您不想养成手写XML的习惯
如果您愿意,您可能会喜欢动态对象和ExpandoObject()。这些类型一起消除了所有类型,并允许您动态创建字典、数组、命名属性等等
最后,ea
public class CustomSerializer
{
public static void Test()
{
var obj = new CustomString {Value = "Random string!"};
var serializer = new CustomSerializer();
var xml = serializer.Serialize(obj);
Console.WriteLine(xml);
var obj2 = serializer.Deserialize<CustomString>(xml);
}
public string Serialize(object obj)
{
var serializer = new XmlSerializer(obj.GetType());
using (var io = new StringWriter())
{
serializer.Serialize(io, obj);
return io.ToString();
}
}
public T Deserialize<T>(string xml)
{
var serializer = new XmlSerializer(typeof (T));
using (var io = new StringReader(xml))
{
return (T)serializer.Deserialize(io);
}
}
}