c# - 使用 DataContractSerializer 反序列化对象中的 XML

标签 c# xml

我有以下 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 属性应该有一项,但它有零项。 我相信,我的契约(Contract)有问题。谁能帮忙?

提前致谢!

最佳答案

调试此类反序列化问题的最佳方法是创建类的内存中示例,然后将其序列化为字符串并将获得的内容与要反序列化的内容进行比较。如果存在差异,那是你的问题。

下面的代码展示了如何为类创建示例序列化 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 assigns a default namespace based on the c# namespace ,在没有任何指令告诉它的情况下。)

您还可以使用 ContractNamespace如果您不想重复执行此操作,请在整个模块或程序集中添加属性。

关于c# - 使用 DataContractSerializer 反序列化对象中的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25251798/

相关文章:

c# - 如何在 C# 中获取 Hotmail 联系人列表?

c# - 未分配的不可空变量的值 (C#)

sql - 如何在 SQL Server 中将 XML 文件读取为表格格式

java - GWT + Hibernate 多对一 xml O/R 映射 : SerializationException

Java 合成 XML : Button Style properties won't work

c# - 正则表达式分组不返回值

c# - 在C# 4.0中如何删除指定xmlnode的所有子节点?

java - Java从上到下读取文件夹中的文件

c# - 如何将 queryString 值更改为 (int)

java - 优化 Web 服务的 XML 响应