0

最近,我们在 .NET (.asmx) 网络服务中看到了这样的异常:

System.Web.Services.Protocols.SoapException: Server was unable to read request. ---> System.InvalidOperationException: There is an error in XML document (868, -3932). ---> System.Xml.XmlException: '.', hexadecimal value 0x00, is an invalid character. Line 868, position -3932.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.Throw(String res, String[] args)
   at System.Xml.XmlTextReaderImpl.Throw(Int32 pos, String res, String[] args)
   at System.Xml.XmlTextReaderImpl.ThrowInvalidChar(Int32 pos, Char invChar)
   at System.Xml.XmlTextReaderImpl.ParseNumericCharRefInline(Int32 startPos, Boolean expand, BufferBuilder internalSubsetBuilder, Int32& charCount, EntityType& entityType)
   at System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars)
   at System.Xml.XmlTextReaderImpl.ParseText()
   at System.Xml.XmlTextReaderImpl.ParseElementContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlTextReader.Read()
   at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.Read()
   at System.Xml.XmlReader.ReadElementString()
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read14_SendErrlog()
   at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer12.Deserialize(XmlSerializationReader reader)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
   at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
   --- End of inner exception stack trace ---
   at System.Web.Services.Protocols.SoapServerProtocol.ReadParameters()
   at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

如何调试此异常?SOAP 过滤器向我们报告此异常,该过滤器在 message.Stage = SoapMessageStage.AfterSerialize 中查找异常。

有什么办法可以得到最初的肥皂请求?如何在第 868 行 -3932 列获取无效字符?3932怎么会有负列?

4

3 回答 3

3

这是关于 Microsoft Web 服务方法的令人讨厌的事情之一——如果请求不能反序列化为 Web 方法签名中的对象,那么服务使用者会收到一条神秘的消息。最重要的是,该请求永远不会进入您的 Web 服务,因为它无法反序列化,因此您无法优雅地处理错误。

对于这些类型的问题,我会做的是创建一个新的 SoapExtension,它只是让您将原始 XML 输出到您方便的目的地(文件或跟踪由 DebugView 或您喜欢的任何其他内容读取)。代码将进入 BeforeDeserialize 阶段。如果您想调查其中一个问题,您可以通过 web.config 启用 SoapExtension。使用 web.config 添加 SoapExtension 的缺点是它将在整个 Web 应用程序中处于活动状态。如果需要,您可以添加一些额外的自定义配置,允许您的服务仅记录特定端点或特定 Web 方法的信息。

通常,只需查看传入的 XML,您就可以看出问题所在。如果没有,那么您可以尝试通过调用 XML 序列化程序的小程序手动运行捕获的 XML,看看是否可以找出发生了什么。另一个有用的工具是Web Service Studio 2,它是一个测试工具,可让您输入数据并调用您的服务(还可以提交您想要的任何 XML)。

就您的具体问题而言,这是我的看法/猜测。看起来 ASCII 字符 null 正在被编码并发送到根据 XML 规范无效的服务。简单的答案是不发送该字符。但是谁在发送那个角色?它是 .NET 客户端吗?你对客户有控制权吗?如果您需要解决其他人的错误,那么您可能必须将有问题的字符替换为另一个字符(可能是空字符串)。

于 2009-06-08T06:32:52.107 回答
2

您应该能够通过使用另一个 SoapExtension 来获取原始消息。事实上,同样的扩展可能会被修改为输入的副本,如果没有异常则丢弃它。如果发生异常,您可以使用原始输入。

您还可以使用 Fiddler 等外部工具来查看发送给您的内容。

于 2009-06-05T17:37:06.773 回答
0

仅供参考:SoapException.Message 故意含糊其辞,以防止暴露太多可能被用于利用系统的信息。

对于您的特殊情况,我会采纳 John 的建议并安装 Fiddler 来监控实际的 HTTP 流量并查看在线消息。

跳出我的异常部分是“十六进制值 0x00,是一个无效字符”,但是正如您提到的那样,它指向的行号是双层的——所以它并不具体。

你向服务传递什么样的参数?您是否正在使用 SOAP 扩展进行任何类型的自定义编码?是否添加了任何其他 SOAP 标头?

于 2009-06-05T21:27:46.520 回答