【问题标题】:C# Deserialization problemC#反序列化问题
【发布时间】:2010-11-12 15:08:27
【问题描述】:

我有以下课程:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:eu.emsa.ssn")]
public partial class SSN_ReceiptType {

    private Header1Type headerField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Order=0)]
    public Header1Type Header {
        get {
            return this.headerField;
        }
        set {
            this.headerField = value;
        }
    }
}

还有以下 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <SSN_Receipt xmlns="urn:eu.emsa.ssn">
        <Header StatusMessage="SomethingSomething" StatusCode="Blabla" SSNRefId="N/A" MSRefId="2674762" Version="2.0" To="NCANOHAU1" SentAt="2010-11-12T14:48:44Z" From="SSN"/>
    </SSN_Receipt>

我使用这种类型化的方法进行反序列化(通过调用 Deserialize(xmlGoesHere)):

    /// <summary>
    /// Deserialize xml string to object of type T
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="xml"></param>
    /// <returns></returns>
    public static T Deserialize<T>(string xml)
    {
        try
        {

            // Create serializer
            var xs = new XmlSerializer(typeof(T));

            // Deserialize
            T t = (T)xs.Deserialize(new StringReader(xml));

            return t;
        }
        catch (Exception e)
        {
            log.Error(string.Format("Unable to deserialize XML: {0}", xml), e);

            return default(T);
        }
    }

现在这是踢球者。这曾经奏效。但最近我们收到了用于生成类的 XSD 的新版本,在生成新代码后(该类未更改,如上所示)我在尝试反序列化时收到以下异常:

System.SystemException: "XML 文档中存在错误 (1, 57)"

此外:

System.InnerException: 不是预期的。

什么鬼? :S 我尝试添加一个指定“SSN_Receipt”的 XmlRootAttribute,但一点帮助都没有。有谁知道怎么回事?

更新:XSD 中的相关部分:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:ssn="urn:eu.emsa.ssn" 
    attributeFormDefault="unqualified" 
    elementFormDefault="qualified" 
    targetNamespace="urn:eu.emsa.ssn">
[...]
<xsd:element name="SSN_Receipt" type="ssn:SSN_ReceiptType"/>
[...]
<xsd:complexType name="SSN_ReceiptType">
    <xsd:annotation>
        <xsd:documentation xml:lang="en"/>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element name="Header" type="ssn:Header1Type"/>
    </xsd:sequence>
</xsd:complexType>

【问题讨论】:

  • 请注意您的语言。这是一个社区论坛。
  • xsd文件有什么区别?
  • @Dan Puzey:tvanfosson 打败了你。 :)
  • 您能列出新的 XSD 吗?部分吗? (根元素和你的元素定义)
  • @Evan:对不起,不会再发生了。

标签: c# xml serialization xml-serialization


【解决方案1】:

为了其他可怜的灵魂将来参考,这是我想出的解决方案。

正如我的问题中提到的,我的类是从 XSD 生成的。我测试了我们课程的早期版本,它们仍然可以正常工作。此外,使用相同类的 SOAP 服务也可以工作。检查跟踪日志,我看不到任何特别的信息。

但我找到了一个具体的解决方案。我在我的类中添加了以下属性:

[System.Xml.Serialization.XmlRoot(Namespace = "urn:eu.emsa.ssn", 
                                  ElementName = "SSN_Receipt")]

现在,我不想在生成的类中乱扔自定义代码,所以我添加了一个部分类:

[System.Xml.Serialization.XmlRoot(Namespace = "urn:eu.emsa.ssn", 
                                  ElementName = "SSN_Receipt")]
public partial class SSN_ReceiptType {}

这完全解决了我的问题。但我仍然不明白为什么这首先会崩溃。

如果有人能提出一个很好的可测试答案来说明它为什么会崩溃,我会做出正确的答案。

感谢您的宝贵时间!在某种程度上,这是一次教育经历:)

【讨论】:

  • 哇,真奇怪:我希望 xsd.exe 在你的类上生成这个属性。好吧,如果我遇到这个问题,我将不得不记住这个。
【解决方案2】:

我很确定你的 xml 应该是这样的

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ssn:SSN_Receipt xmlns="urn:eu.emsa.ssn"> 
    <ssn:Header StatusMessage="SomethingSomething" StatusCode="Blabla" SSNRefId="N/A" MSRefId="2674762" Version="2.0" To="NCANOHAU1" SentAt="2010-11-12T14:48:44Z" From="SSN"/> 
</ssn:SSN_Receipt> 

【讨论】:

  • 元素的前缀应该是 ssn:
  • 修改后的 XML 现在生成以下内容:“ssn”是一个未声明的命名空间。第 1 行,位置 57。
  • xml 是否必须包含 xsd 验证。你不能有一半,所以如果包含,必须使用 SSN_Receipt 元素上的 xsi:schemaLocation 属性包含 xsl 位置,否则 xml 不应该具有 xmlns 属性。 xsi:schemaLocation="urn:eu.emsa.ssn C:\pathtomyxsd\xsdfile.xsd"
  • 我不确定我是否理解,我认为 ssn 前缀只能在架构中使用。
  • 请记住,这以前可以工作 -- xsd 中的任何相关内容都没有改变,我生成的代码或多或少是相同的。
【解决方案3】:

您应该生成了一个SSN_Receipt 类。在将它传递给反序列化方法时,您需要使用该类。

IE:

Deserialize<SSN_Receipt>(xmlGoesHere);

而不是SSN_ReceiptType

【讨论】:

  • 我不太确定——如果您查看 XSD,生成的代码是否有意义。元素名称为 SSN_Receipt,但类型名称为 SSN_ReceiptType。
猜你喜欢
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-26
  • 2013-12-25
相关资源
最近更新 更多