【问题标题】:c#, cannot DeSerialize XMl filec#,无法反序列化 XML 文件
【发布时间】:2014-02-15 22:26:01
【问题描述】:

我需要向网络服务发送请求。这个请求要求一个“会话”对象作为参数。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18060")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.xmlns.cfins.com/cfins/services/publishPolicyData/1.0")]
public partial class session {

    private object[] itemsField;

    private string idField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("data", typeof(sessionData))]
    [System.Xml.Serialization.XmlElementAttribute("properties", typeof(sessionProperties))]
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }
}

这是我的 xml 文件。

    <session id="6055">
      <properties dateModified="2014-01-08" engineVersion="2.0" cultureCode="en-US" cultureName="United States [english]">
        <userName>admin</userName>
      </properties>
      <data id="d2311A049FDC64CD9AE9EF3DE5874CB2D">
        .....
      </data>
    </session>

当我反序列化这个 xml 文件时,我只得到 id,items 总是空的。顺便说一句,会话类来自网络服务,我无法更改它。

    public static session GetSession()
    {
        var s = new session();
        var data = new sessionData();

        var sessionXml = @"C:\Projects\CFWinSvc - Copy\XmlDeSerialize\session.xml";

        using (TextReader reader = new System.IO.StreamReader(sessionXml))
        {
            var serializer = new XmlSerializer(typeof(session));
            s = (session)serializer.Deserialize(reader);
        }

        return s;

    }


    public static session GetSession()
    {
        var s = new session();
        var data = new sessionData();


        var sessionXml = @"C:\Projects\CFWinSvc - Copy\XmlDeSerialize\session.xml";

        using (TextReader reader = new System.IO.StreamReader(sessionXml))
        {
            var serializer = new XmlSerializer(typeof(session));
            s = (session)serializer.Deserialize(reader);
        }

        return s;

    }

更新:

这是 XML 架构。

    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema xmlns="http://www.cfins.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.xmlns.cfins.com/cfins/services/publishPolicyData/1.0" elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:element name="session">
            <xs:complexType>
                <xs:sequence>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="properties">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="userName" type="xs:string"/>
                                </xs:sequence>
                                <xs:attribute name="dateModified" use="optional"/>
                                <xs:attribute name="engineVersion" type="xs:string" use="optional"/>
                                <xs:attribute name="cultureCode" type="xs:string" use="optional"/>
                                <xs:attribute name="cultureName" type="xs:string" use="optional"/>
                            </xs:complexType>
                        </xs:element>
                        <xs:element name="data">
                            <xs:complexType>
                                <xs:all>
                                    <xs:element name="AlwaysAddIDs" type="xs:boolean" minOccurs="0"/>
                                    <xs:element name="ProRatingOn" type="xs:boolean" minOccurs="0"/>
                                    <xs:element name="carrier" minOccurs="0">
                                        <xs:complexType>
                                            <xs:attribute name="id" type="xs:string" use="optional"/>
                                        </xs:complexType>
                                    </xs:element>
                                    <xs:element name="userinterface" minOccurs="0">
                                        <xs:complexType>
                                            <xs:attribute name="id" type="xs:string" use="optional"/>
                                        </xs:complexType>
                                    </xs:element>
                                </xs:all>
                                <xs:attribute name="id" type="xs:string" use="optional"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:choice>
                </xs:sequence>
                <xs:attribute name="id" use="optional"/>
            </xs:complexType>
        </xs:element>
    </xs:schema>

【问题讨论】:

    标签: c# xml web-services deserialization xml-deserialization


    【解决方案1】:

    要使用 Xml 序列化,您的所有属性都需要有一个公共的 getter 和 setter,否则反射器会拒绝序列化或反序列化您的对象。

    【讨论】:

      【解决方案2】:

      您的会话课程没有任何问题。 但是,它被标记为

      [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.xmlns.cfins.com/cfins/services/publishPolicyData/1.0")]
      

      这几乎意味着 xml 反序列化器只会考虑您的 session 中位于同一 xml 命名空间中的子元素。

      简而言之,将丑陋的命名空间定义添加到您的 xml 文件中,如下所示:

      <properties xmlns="http://www.xmlns.cfins.com/cfins/services/publishPolicyData/1.0" ...
      

      会成功的:您将在需要的地方获得所有 sessionProperties 和 sessionData。

      【讨论】:

        【解决方案3】:

        XmlElement 不应用于集合或数组属性。 XmlArrayXmlArrayItem 应改为使用。我不知道为什么会像上面显示的那样生成代码。生成后修改了吗?如果您共享您的架构,也许我们可以确定代码生成的问题。

        [XmlArray]
        [XmlArrayItem("data", typeof(sessionData))]
        [XmlArrayItem("properties", typeof(sessionProperties))]
        public object[] Items {
            get {
                return this.itemsField;
            }
            set {
                this.itemsField = value;
            }
        }
        

        【讨论】:

        • 另一个开发人员将 xml 加载到 Visual Studio。从顶部菜单中选择 xml,然后选择创建架构。
        • 再测试一次,我可以使用 Visual Studio 生成模式。但是,如果我使用 xsd.exe,我会收到此错误消息。 “错误:处理 'QASession.xml' 时出错。- 无法将嵌套关系或元素列添加到包含 SimpleContent 列的表中。”
        • 您是从 XML 生成架构,然后从架构生成代码吗?还是您是手动创建模式然后生成代码?请更清楚地描述您的流程。
        • 不是手动的,我们正在使用 Visual Studio 来生成该模式。将 xml 加载到 Visual Studio。从顶部菜单中选择 xml,然后选择创建模式。我只是使用另一个工具“xsd.exe”测试它,这一次,xsd 给了我错误。见上面的评论。但视觉工作室没有任何问题来生成模式。顺便说一句,我在这里发布的 xml 文件是修剪版本。完整版大约2k行,太大了,不能在这里发布。
        • 查看我的上一个commnet,我编辑评论并在那里发布详细信息。
        猜你喜欢
        • 2019-09-24
        • 2013-10-08
        • 2015-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多