0

UPDATE: During further investigation, I realized that the mistake was not in the custom ServiceHostFactory as I originally thought, but in the way I had wrapped OperationContext internally. I'm going to update this question later today.

I recently added a custom ServiceHostFactory to my IIS-hosted WCF web service, in attempt to use Ninject's dependency injection for my service constructor. For some reason, whenever I try to access properties belonging to OperationContext.Current, the following exception trace is thrown:

2015-05-08 10:30:39.5718 MyErrorHandler System.ObjectDisposedException: Message is closed.
   at System.ServiceModel.Channels.BufferedMessage.get_Headers()
   at System.ServiceModel.Channels.DelegatingMessage.get_Headers()
   at System.ServiceModel.OperationContext.get_IncomingMessageHeaders()
... (my code here)
   at SyncInvokeFindCurves(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) 
2015-05-08 10:31:51.2459 MyErrorHandler System.TimeoutException: The service's security session did not receive a 'close' message from the client within the configured timeout (00:00:10).
   at System.ServiceModel.Security.SecuritySessionServerSettings.ServerSecuritySimplexSessionChannel.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.Dispatcher.MessageRpc.CloseChannel() 

In the debugger, I've noticed that the ObjectDisposedException is thrown not just for OperationContext.IncomingMessageHeaders, but also for OperationContext.ServiceSecurityContext and many others.

I've tried several different implementations of a service host factory, including:

  • A custom service host factory that extends ServiceHostFactory and returns a ServiceHost with a custom IInstanceProvider
  • A custom service host factory that extends NinjectServiceHostFactory.

But to no avail, because all of them share this same problem. I've also tried plugging in an IErrorHandler but it still sheds no light on the root cause of this problem. I've also tried googling this error message as well as the components that could have failed but I haven't yet found anything similar to my situation.

Here is the simplest code I can use to illustrate the problem:

public class WorkingServiceHostFactoryWithNinject : NinjectServiceHostFactory
{
    // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
    // ReSharper disable once FieldCanBeMadeReadOnly.Local
    private IKernel _kernel;

    /// <summary>
    /// Initializes the factory.
    /// </summary>
    public WorkingServiceHostFactoryWithNinject()
    {
        _kernel = new StandardKernel();
        _kernel.Bind<IDummyDependency>().To<DummyDependency>();
        ...
        SetKernel(_kernel);
    }
}

My configurations include:

<wsHttpBinding>
  <binding name="ServiceBinding" 
            maxBufferPoolSize="4000000000" 
            maxReceivedMessageSize="2000000000" 
            allowCookies="true">
    <readerQuotas maxDepth="32" 
                  maxBytesPerRead="2000000000"
                  maxStringContentLength="2000000000" 
                  maxArrayLength="2000000000" />
    <security mode="TransportWithMessageCredential">
      <transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
      <message clientCredentialType="UserName" />
    </security>
  </binding>
</wsHttpBinding>

and

<serviceBehaviors>
  <behavior name="ServiceBehavior">
    <serviceCredentials>
      <serviceCertificate findValue="**redacted**" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomUserNamePasswordValidator, MyAssembly" />
    </serviceCredentials>
    <serviceDebug includeExceptionDetailInFaults="true" />
    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
    <serviceSecurityAudit
      auditLogLocation="Application"
      serviceAuthorizationAuditLevel="Failure"
      messageAuthenticationAuditLevel="Failure"
      suppressAuditFailure="true"/>
  </behavior>
</serviceBehaviors>

What I know for sure is that OperationContext.Current didn't behave like this before I wrote my own ServiceHostFactory. It almost seems as if the garbage collector disposes of the message too early...

S. Dixon
  • 842
  • 1
  • 12
  • 26
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders May 08 '15 at 17:04
  • Is any custom behavior inspecting the message? – moarboilerplate May 08 '15 at 17:21
  • No. The only behaviors in use are the ones in the `` config section above. – S. Dixon May 08 '15 at 17:24
  • Can you provide code for your OnClosed override? There may be an issue with that. – moarboilerplate May 08 '15 at 17:47
  • @moarboilerplate - there are no overrides for the ServiceHost object. Also, it appears that my analysis was wrong. It looks like OperationContext properties ARE being initialized, but they are being disposed of before I end up using them. In other words, this is not an issue related to the service host or the service host factory, but with my wrapper class for OperationContext. Sorry about the inconvenience. – S. Dixon May 08 '15 at 19:07

0 Answers0