Optional parameter of at UriTemplate causes twice invoces of AfterReceiveRequest - WCF - IDispatchMessageInspector RRS feed

  • Question

  • I just dived a little deeper into it and discovered new details.

    Not the 'UriTemplate' in general causes the 2nd invocation of 'AfterReceiveRequest' but the optional parameter within!

    If I call the method by "http://server/result/val1" AfterReceiveRequest will be invoked twice.

    If I pass all possible parameters like "http://server/result/val1/val2/val3" there will be no useless invocation. Is that behavior as intended?

    UriTemplate = "result/{para1=null}/{para2=null}/{para3=null}"

    --- following the initial post, just for information ---

    While implementing a WCF REST Service System I stuck on a problem with the http-headers.

    In my `ServiceContract` there is a method with an `UriTemplate` definition at the `WebGet` attribute, so it can be called via

        http://server/result/val1/val2 ...
    instead of

        http://server/MyMethod?para1=val1&para2=val2 ...

    (I need this because of compatibility reasons.)

    Also there is a significant value in the http-headers collection, that I need to read. Therefore I implement `IDispatchMessageInspector` and add this inspector to the `EndpointDispatchers` `MessageInspectors` collection. By that the `AfterReceiveRequest` will be invoked by WCF and I can access `WebOperationContext.Current.IncomingRequest.Headers` to read the desired Value.

    The Problem:

    WCF solves the `UriTemplate`-mapping by generating a second request to the destination method, but does not pass the header entries from the original call to the generated second call. So `AfterReceiveRequest` (and of course `BeforeSendReply`, too) will be invoked twice, but the header-values from the real client call are only included in the first call.

    Also I found no way to correlate the first and the second `AfterReceiveRequest` call, to implement a "special way" for passing the header-value from the first to the second call.

    Is there a way to tell WCF to route the headers to the `UriTemplate`-redirected second call?

    Here are some code fragments to make it clear:  

        public interface IMyService
            [WebGet(UriTemplate = "result/{para1=null}/{para2=null}/{para3=null}")]
            bool MyMethod(string para1, string para2, string para3);
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        public class MyService : IMyService
            public bool MyMethod(string para1, string para2, string para3)
                return DoTheWork();
        public class MyServiceInspectorBeavior : Attribute, IServiceBehavior
            public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
                foreach (EndpointDispatcher epDispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>().SelectMany(cDispatcher => cDispatcher.Endpoints))
                    epDispatcher.DispatchRuntime.MessageInspectors.Add(new MyInspector());
        public class MyInspector : IDispatchMessageInspector
            //this is invoked twice for each client request, 
            //but only at the first call the header is present...
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
                WebHeaderCollection webOpContext = 
                string xForwardedIp = webOpContext["X-FORWARDED-IP"];
                return OperationContext.Current.IncomingMessageProperties["ActivityId"];

    • Edited by Heiko Wrede Thursday, September 25, 2014 3:31 PM new facts
    Thursday, September 25, 2014 9:16 AM

All replies

  • I think the principals of REST are violated when you pass parameters on the query string, and especially so when you pass multiple query string parameters.

    If you need to pass more than one parameter into the service you can use a comma separated list. For example, a service which draws a rectangle could receive two integers representing the length of the sides as input, separated by a comma.

    Friday, September 26, 2014 8:44 AM