代码之家  ›  专栏  ›  技术社区  ›  Jay S

.NET SOAP扩展正在MethodInfo中引发NullReferenceException?

  •  2
  • Jay S  · 技术社区  · 16 年前

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

    大家好,

    我正在记录对数据库的WebService调用,最后使用一个从另一个项目移植过来的非常简单的实现配置和运行了soapextension。我已经在配置文件中设置了它,所以它将针对所有方法运行。当我调用WebService并且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)
    

    在processmessage(soapmessage)的beforereserialize阶段调用loginput方法:

    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(),并在其中引发空引用异常。我在谷歌上搜索了一下,查看了这里的堆栈溢出情况,但还没有找到为什么MethodInfo属性会抛出异常。

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

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

    2 回复  |  直到 16 年前
        1
  •  2
  •   Jay S    16 年前

    经过反复试验,我终于解决了这个问题。虽然我不完全理解原因,但是soapmessage对象没有在beforereserialize阶段完全初始化。Action和MethodInfo属性在此阶段都会引发错误。

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

    正确的顺序是:

    1. 预先初始化

      A.读取服务器URL

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

      c.从流中读取请求内容

    2. 序列化

      A.读取异常

      b.读取MethodInfo信息(必要时还可读取操作信息)

      c.从流中读取响应内容

        2
  •  1
  •   Thedric Walker    16 年前

    根据msdn,方法信息仅在反序列化和预序列化期间可用。所以这是问题的一部分。