.NET SOAP 扩展在 MethodInfo 中抛出 NullReferenceException?

标签 .net web-services exception soap-extension

注意:使用.NET 2.0和VS2005作为IDE

大家好,

我正在努力将 Web 服务调用记录到我们的数据库中,并最终使用从另一个项目移植过来的非常精简的实现来配置和运行 SoapExtension。我已在配置文件中对其进行了设置,因此它将针对所有方法运行。当我调用 Web 服务并且 SOAP 扩展触发时,当 SoapServerMessage 尝试调用其 MethodInfo 属性时,会引发 NullPointerException:

System.Web.Services.Protocols.SoapException: There was an exception running the extensions specified in the config file. 
---> System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.Services.Protocols.SoapServerProtocol.get_MethodInfo()
at System.Web.Services.Protocols.SoapServerMessage.get_MethodInfo()
at MyService.SOAPLoggingExtension.LogInput(SoapMessage message)
at MyService.SOAPLoggingExtension.ProcessMessage(SoapMessage message) 
at System.Web.Services.Protocols.SoapMessage.RunExtensions(SoapExtension[] extensions, Boolean throwOnException)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

LogInput 方法在 ProcessMessage(SoapMessage) 的 BeforeDeserialize 阶段调用:

SoapMessageStage.BeforeDeserialize:
   CopyStream(_oldStream, _newStream);
   _newStream.Position = 0;

   if(_enabled)
      LogInput(message);
   break;

当尝试访问它尝试记录的消息对象的 MethodInfo 属性时,LogInput 方法失败。这是调用该属性的代码块:

entry = new MyServerLogEntry();
entry.ServerURL = message.Url;
entry.Method = (message.MethodInfo == null) ? null : message.MethodInfo.Name;

当调用 message.MethodInfo 时,它会冒泡到 SoapServerProtocol.get_MethodInfo(),并在那里抛出空引用异常。我用谷歌搜索,并在 Stack Overflow 上进行了检查,但无法找出 MethodInfo 属性会抛出异常的原因。

有谁知道如何确保在 Web 服务调用期间正确初始化此 MethodInfo 属性?

其他详细信息:如果我不尝试访问 MethodInfo 属性,扩展程序将正常工作并记录到我的数据库。

最佳答案

经过一番尝试和错误,我已经能够解决这个问题。虽然我不完全理解为什么,SoapMessage 对象在 BeforeDeserialize 阶段没有完全初始化。 Action 和 MethodInfo 属性都会在此阶段抛出错误。

但是,在 AfterSerialize 阶段,这些对象似乎已正确初始化。通过将读取消息名称的行移到后面的阶段,可以正确填充日志条目对象而不会引发异常。

看来正确的顺序是:

  1. 反序列化之前

    a.读取服务器 URL

    b.检索请求信息(证书、用户主机地址等)

    c.从流中读取请求内容

  2. 序列化后

    a.阅读异常

    b.读取 MethodInfo 信息(如果需要,还可以读取 Action 信息)

    c.从流中读取响应内容

关于.NET SOAP 扩展在 MethodInfo 中抛出 NullReferenceException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/226587/

相关文章:

c# - DateTime.ParseExact 格式字符串

c# - 如何判断一个点是否属于某条线?

c# - 从 Visual Studio 安装项目安装 SQL Server 和 .NET Framework

c# - 如何通过 ServiceBehavior 配置启用 WCF 帮助页面?

c++ - 抛出异常是一种健康的退出方式吗?

.net - 如何使用 PDFsharp .NET 库将 PDF 页面导出为图像?

c# - Moq 网络服务的数据源

java - 将 SOAP XML 响应写入文件

java - 设置外观时序列化 AbstractTableModel 失败

spring - 未调用 ResponseEntityExceptionHandler 的重写 handleMethodArgumentNotValid 方法