如何调试损坏的肥皂请求?

发布于 2024-07-23 10:55:09 字数 2315 浏览 14 评论 0原文

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

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栏?

Lately, we've been seeing exceptions like this in our .NET (.asmx) webservices:

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()

How can I debug this exception? This exception is getting reported to us from a SOAP filter which looks for exceptions in message.Stage = SoapMessageStage.AfterSerialize.

Is there any way to get at the original soap request? How do I get an invalid character at line 868, column -3932? How can there a negative column 3932?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

可爱咩 2024-07-30 10:55:09

这是 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 客户端吗? 你对客户有控制权吗? 如果您需要解决其他人的错误,那么您可能必须用另一个字符(可能是空字符串)替换有问题的字符。

This is one of the irritating things about the Microsoft web services approach -- if the request cannot be deserialized into the objects in your web method signature then the service consumer gets a cryptic message. And to top it off, the request never makes it into your web service because it cannot be deserialzied so you can't handle the error gracefully.

What I would do to help with these types of issues is to create a new SoapExtension that simply lets you output the raw XML to a destination that is convenient for you (file or Trace to be read by DebugView or whatever else you like). The code would go in the BeforeDeserialize stage. You could enable the SoapExtension via web.config in the event you wanted to investigate one of these issues. The downside of using the web.config to add the SoapExtension is that it will be active for the entire web application. You could add some additional custom configuration that would allow your service to only log information for a specific endpoint or a specific web method if you wanted.

Usually, just by seeing the incoming XML you can see what the problem is. If not, then you could try to manually run the captured XML through small program that invokes the XML serializer and see if you can find out what is going on. Another useful tool is Web Service Studio 2 which is a test harness which lets you enter data and invoke your service (and also submit any XML you want).

In terms of your specific issue, here is my take/guess. It looks like ASCII character null is getting encoded and sent to your service which is invalid according to the XML Spec. The simple answer is not to send that character. But who is sending that character? Is it a .NET client? Do you have control over the client? If you need to work around someone else's bug, then you may have to replace the offending character(s) with another character (perhaps empty string).

演多会厌 2024-07-30 10:55:09

您应该能够使用另一个 SoapExtension 获取原始消息。 事实上,可以修改相同的扩展来制作输入的副本,并在没有例外的情况下丢弃它。 如果发生异常,您就可以使用原始输入。

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

You should be able to get the original message by using another SoapExtension. In fact, the same extension could probably be modified to make a copy of the input, and to discard it if there is no exception. The original input would then be available to you if an exception occurred.

You could also use an external tool like Fiddler to watch what's being sent to you.

梦里兽 2024-07-30 10:55:09

仅供参考:SoapException.Message 故意保持模糊,以防止暴露太多可能被用来利用系统的信息。

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

你的异常部分让我跳出来的是“十六进制值0x00,是一个无效字符”,但正如你提到的它指向的行号是废话——所以它不是具体的。

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

FYI: SoapException.Message is intentionally left vague to prevent exposing too much information which could potentially be used to exploit the system.

For your particular case I'd take John's advice and install Fiddler to monitor the actual HTTP traffic and view the message on the wire.

The portion of your exception that jumps out at me is the "hexadecimal value 0x00, is an invalid character" but as you mentioned the line number it points to is bunk--so it's nothing concrete.

What kind of parameters do you pass to the service? Are you doing any kind of custom encoding with a SOAP extension? Any additional SOAP headers being added?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文