我有以下xml:
<ArrayOfString>
<stringValues>
<stringvalue>teste1</stringvalue>
<stringList>
<stringText>stringList1</stringText>
</stringList>
</stringValues>
</ArrayOfString>
我的合同如下:
[KnownType(typeof(StringList))]
[DataContract(Name = "stringValues", Namespace = "")]
public class StringValues
{
[DataMember(Name="stringvalue",Order=1)]
public string stringvalue { get; set; }
[DataMember(Name="stringList",Order=2)]
public StringList stringList { get; set; }
}
[CollectionDataContract(ItemName = "stringText")]
public class StringList : List<string>
{
}
用于反序列化的代码是:
var testexml = @"<ArrayOfString>
<stringValues>
<stringvalue>teste1</stringvalue>
<stringList>
<stringText>stringList1</stringText>
</stringList>
</stringValues>
</ArrayOfString>";
XmlDictionaryReader stringsReader = XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create(new StringReader(testexml)));
DataContractSerializer ArrayOfString = new DataContractSerializer(typeof(List<StringValues>), "ArrayOfString", "");
var strings = ArrayOfString.ReadObject(stringsReader);
当我运行它时,stringList属性应该具有一项,但它具有零项。我相信,我的合同出了点问题。有人可以帮忙吗?
提前致谢!
调试此类反序列化问题的最佳方法是创建一个内存中的类示例,然后将其序列化为字符串,然后将所获得的内容与要反序列化的内容进行比较。如果存在差异,那就是您的错误。
这是显示如何为类创建示例序列化XML的代码:
private static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
}
private static string GetXml<T>(T obj, DataContractSerializer serializer) where T : class
{
using (var textWriter = new StringWriter())
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = " "; // The indentation used in the test string.
using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
{
serializer.WriteObject(xmlWriter, obj);
}
return textWriter.ToString();
}
}
public static string GetXml<T>(T obj) where T : class
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
return GetXml(obj, serializer);
}
注意-不是您问题的完整答案,但是代码可能有用,并且注释太长。
更新
好吧,我自己尝试过。您需要将上层类的DataContract上的命名空间设置为与嵌套类的命名空间相同,并且与XML文件本身中给出的命名空间相同:
[CollectionDataContract(ItemName = "stringText", Namespace="")]
public class StringList : List<string>
{
}
如果不这样做,DataContractSerializer
将假定它们位于不同的命名空间中,并期望如下所示:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfstringValues xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<stringValues>
<stringvalue>teste1</stringvalue>
<stringList xmlns:d3p1="http://schemas.datacontract.org/2004/07/Clr.Namespace">
<d3p1:stringText>stringList1</d3p1:stringText>
</stringList>
</stringValues>
</ArrayOfstringValues>
Clr.Namespace
您在其中定义类的CLR名称空间在哪里。(是的,显然在没有任何其他说明的情况下,DataContractSerializer
基于c#名称空间分配了默认名称空间。)
ContractNamespace
如果不想重复执行此操作,也可以在整个模块或程序集上使用该属性。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句