【问题标题】:InvalidOperationException while SOAP serialization of complex type复杂类型的 SOAP 序列化时出现 InvalidOperationException
【发布时间】:2010-11-03 22:25:19
【问题描述】:

我遇到了 SOAP 序列化的问题,如果能找到答案就太好了。这是一个非常简化的示例:

public void Test()
{
    StringBuilder sb = new StringBuilder();
    StringWriter writer = new StringWriter(sb);

    SoapReflectionImporter importer = new SoapReflectionImporter();
    XmlTypeMapping map = importer.ImportTypeMapping(typeof(A));
    XmlSerializer serializer = new XmlSerializer(map);
    serializer.Serialize(writer, new A());
}

[Serializable]
public class A
{
    public A()
    {
        BB = new B();
    }

    public int a;

    public B BB;
}
[Serializable]
public class B
{
    public int A1 { get; set; }

    public int A2 { get; set; }
}

如果我运行 Test() 方法,则会收到以下异常:System.InvalidOperationException: Token StartElement in state Epilog would result in an invalid XML document.

不胜感激。

【问题讨论】:

    标签: c# .net serialization soap


    【解决方案1】:

    只是一个注释, 如果流的位置未设置为流的开头,则上面的示例将不起作用。像这样:

    Stream s = new MemoryStream();
    XmlWriter writer = new XmlTextWriter(s, Encoding.UTF8);
    
    SoapReflectionImporter importer = new SoapReflectionImporter();
    XmlTypeMapping map = importer.ImportTypeMapping(typeof(A));
    XmlSerializer serializer = new XmlSerializer(map);
    writer.WriteStartElement("root");
    serializer.Serialize(writer, new A());
    
    s.Position = 0;
    StreamReader sr = new StreamReader(s);
    string data = sr.ReadToEnd();
    

    【讨论】:

    • 谢谢,很高兴我一直在阅读。我得到了一个空的数据字符串,但是在看到这个之后它就可以工作了!
    • 救命稻草!这应该是完整的答案。
    • 这给出了空白字符串!!!我很沮丧,没有人能解决这个问题
    【解决方案2】:

    使用 XmlWriter 代替 StringWriter 并执行 writer.WriteStartElement("root");

    这将起作用:

    Stream s = new MemoryStream();
    XmlWriter writer = new XmlTextWriter(s, Encoding.UTF8);
    
    SoapReflectionImporter importer = new SoapReflectionImporter();
    XmlTypeMapping map = importer.ImportTypeMapping(typeof(A));
    XmlSerializer serializer = new XmlSerializer(map);
    writer.WriteStartElement("root");
    serializer.Serialize(writer, new A());
    
    StreamReader sr = new StreamReader(s);
    string data = sr.ReadToEnd();
    

    【讨论】:

    • 谢谢,这有帮助。但我还有另一个问题,这次是荒漠化。如果我在类 A 中重写方法 GetHashCode() 并尝试访问属性 BB,则在反序列化期间会出现 NullReferenceException。不知何故,属性 BB 等于 0,但它不应该。
    • 好吧,我已将问题本地化。反序列化器的行为很奇怪,它创建了反序列化类的新实例(通过调用默认构造函数),之后它手动将所有字段和属性设置为其默认值。这意味着它将引用类型属性设置为 null。然后反序列化器调用 GetHashCode() 和 Equals() 等方法。但是我自己对这些方法的实现“知道”属性永远不会为空。这导致了异常。我刚刚更改了 GetHashCode() 和 Equals() 中的代码,现在他们“知道”属性可以为空。感谢您的帮助!
    • XML 序列化程序不关注非默认构造函数,也不关注索引器、运算符或其他任何东西。它基本上是为了序列化一个类的公共读/写属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 2013-04-03
    • 1970-01-01
    相关资源
    最近更新 更多