如何调试损坏的soap请求?

时间:2009-06-05 15:13:49

标签: web-services asmx soapexception

最近,我们在.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()

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

有没有办法获得原始的肥皂要求?如何在第868行-3932列中获得无效字符?怎么会有否定列3932?

3 个答案:

答案 0 :(得分:3)

这是关于Microsoft Web服务方法的一个令人恼火的事情 - 如果请求无法反序列化到Web方法签名中的对象,则服务使用者会收到一条神秘的消息。最重要的是,请求永远不会进入您的Web服务,因为它无法反序列化,因此您无法正常处理错误。

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

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

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

答案 1 :(得分:2)

您应该可以使用另一个SoapExtension获取原始邮件。实际上,可能会修改相同的扩展名以生成输入的副本,并在没有异常时将其丢弃。如果发生异常,则可以使用原始输入。

您还可以使用像Fiddler这样的外部工具来观看发送给您的内容。

答案 2 :(得分:0)

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

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

你跳出来的异常部分是“十六进制值0x00,是一个无效字符”,但正如你所提到的那样,它指向的行号是bunk - 所以它没什么具体的。

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