.netwcficlientmessageinspector

AfterReceiveReply is not invoked for void methods


We have a requirement to log requests without replies (in case of timeout). We are using implementation of IClientMessageInspector to do this. Unfortunately there is second case in which AfterReceiveReply is not invoked - when the service method is void (does not return anything). Is there any way to recognize void method in BeforeSendRequest method?


Solution

  • There's no pretty way to do so but I have found an ugly one :)

        /// <summary>
        /// Checks internal operation formatter for action reply attribute which is empty for one way methods.
        /// Based on above returns whether service method will have reply or not.
        /// </summary>
        /// <param name="request">Request message.</param>
        /// <returns>Whether service method will have reply.</returns>
        private bool WillRequestHaveReply(Message request)
        {
            FieldInfo operationFormatterField =
                request.GetType()
                    .GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                    .FirstOrDefault(f => f.Name == "operationFormatter");
    
            if (operationFormatterField != null)
            {
                object operationFormatter = operationFormatterField.GetValue(request);
                if (operationFormatter != null)
                {
                    PropertyInfo actionReplyProperty =
                        operationFormatter.GetType()
                            .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)
                            .FirstOrDefault(p => p.Name == "ReplyAction");
    
                    if (actionReplyProperty != null)
                    {
                        return actionReplyProperty.GetValue(operationFormatter) != null;
                    }
                }
            }
    
            // Every request should have operationFormatter inside.
            // Use standard behaviour (requests with replies) if it doesn't.
            return true;
        }