none
Cancel request from IDispatchMessageInspector RRS feed

  • Question

  • Referring to this article: http://blogs.msdn.com/b/zelmalki/archive/2008/12/29/creating-a-wcf-idispatchmessageinspector.aspx

    The article suggests that to cancel a request we simply need to set the request to null.  This works however, it causes wcf to throw an exception which causes most of the slowness in my service.  In the Wcf Trace Viewer it shows taking an extra ~400ms to process the request.

     

    Stack Trace:

    at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
    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)

     

    Is there a way to gracefully flag this message as being invalid without setting it to null?

    Thanks,

    Monday, August 23, 2010 8:20 PM

Answers

All replies

  • Have you tried throwing a FaultException to return an error to the client?
    Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
    Twitter: richardblewett
    Tuesday, August 24, 2010 8:15 AM
    Moderator
  • Currently, what i'm trying to do is mimic basic authorization through a rest endpoint.  This way i'll be able to validate the credentials through a custom data source.  In this scenario, i don't think a faultexception (or webfaultexception) would be the best approach.

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
          if (this.IsHelpRequest())
            return null;
    
          string[] credentials = this.ExtractCredentials(request);
    
          if (credentials == null)
          {
            request = null;
            return (bool?)false;
          }
    
          try
          {
            //Validate
     } catch { request = null; return (bool?)false; } return null; } public void BeforeSendReply(ref Message reply, object correlationState) { if ((bool?)correlationState == false) { HttpResponseMessageProperty responseProperty = new HttpResponseMessageProperty(); responseProperty.StatusCode = System.Net.HttpStatusCode.Unauthorized; responseProperty.Headers.Add("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", "Universe")); reply.Properties[HttpResponseMessageProperty.Name] = responseProperty; } }

    Tuesday, August 24, 2010 12:51 PM
  • Hello,

    do you host your REST service in IIS? If so than use HttpModule for Basic authentication against custom credentials source.

    Best regards,
    Ladislav

    Tuesday, August 24, 2010 1:00 PM
  • Hi and thanks for the reply,

    I tried going about using a http module in the beginning but it wasn't as straight forward.  Let me explain the project a little further.

    First, our database is set up so that we don't have a table (like dbo.Employees) to validate the login/password.  We actually have to attempt to connect (through a socket) to the database using the provided credentials. 

    The problem i ran into was that i needed to keep the same socket instance through the lifetime of the request.  This keeps me from having to spin up multiple socket connections (one to validate credentials, one to process the web service operation, etc).  To get around that problem, I wrap the socket in an IExtension<OperationContext> object (my custom context) and add it to OperationContext.Current.Extensions to be retrieved later in the service operation. 

    My soap endpoints are set up with wshttpbinding and custom username authentication and it works perfectly.

    The rest endpoints are a little difficult because i don't have access to OperationContext.Current until later on in the request.  Using validating the credentials in an HttpModule isn't going to work for me because the OperationContext hasn't be constructed yet and therefore i cannot add my custom context to the Extensions collection.  So, i could make a public static variable to store the my custom context somewhere for REST requests but, then i'll need to code checks everywhere to figure out where to get my custom context.

     

    Hopefully i didn't bore you with too many details!

    Thanks,

    Tuesday, August 24, 2010 1:37 PM
  • Hi,

    Have you looked at this blog:

    http://weblogs.asp.net/cibrax/archive/2009/03/20/custom-basic-authentication-for-restful-services.aspx

    Hope this helps.

    Thanks

    Binze


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Bin-ze Zhao Tuesday, August 31, 2010 6:54 AM
    Friday, August 27, 2010 9:54 AM
  • Hi Richard Blewett,

    My includeExceptionDetailInFaults is "false". If I throw a FaultException in the operation method, I can get the fault on my client. But If I throw a FaultException in the message inspector, I can not get the fault on my client. Could help me with this problem?

    Thank you in advance. And forgive my bad English..

    Thursday, October 27, 2011 8:07 AM