4

Is there something Like ActionFilterAttribute (From ASP.NET MVC) in WCF Services (Or anything like that). basically what I want to do is to log what is coming and goint to and from my services, and I don't want to write the logging code in every single ServiceContracts. yes the question is very general but you understand the idea what I want to do.

Dimitri
  • 2,798
  • 7
  • 39
  • 59
  • 1
    possible duplicate of [WCF service attribute to log method calls and exceptions](http://stackoverflow.com/questions/13655541/wcf-service-attribute-to-log-method-calls-and-exceptions) – Pharabus Jul 25 '14 at 13:30

2 Answers2

5

Yes there is it called as MessageInspectors/ParameterInspectors , here you can read about them http://msdn.microsoft.com/en-us/library/aa717047%28v=vs.110%29.aspx

This is exactly what you are looking for , WCF custom behavior log logging http://www.codeproject.com/Articles/243352/LoggingBehavior-How-to-Connect-Log-prints-with-the

Only confusing thing is you can have message inspector on WCF service and WCF proxy as well , in your case you need only for service side

Ajay Kelkar
  • 4,591
  • 4
  • 30
  • 29
1

I had to read a lot to find this out, I'm not an expert in WCF but given this information is a little scarce I'm sharing what have worked for me.

My Solution consists of using an OperationBehavior and a DispatcherMessageInspector

OperationBehavior

  • Allows you to change the binding information, validate de operation description, and apply dispatcher behaviors.

DispatcherMessageInspector

  • Allows you to inspect and change the messages that are sent for your service.

Dispatcher

  • Gets the messages from the communication channels and sends to the right operation, and get the result back to the caller.

Service Operation

  • are your service methods

CODE SOLUTION

MESSAGE INSPECTOR

   public class MyMessageInspector : IDispatchMessageInspector
    {
        List<string> targetOperations = new List<string>();

        public MyMessageInspector(OperationDescription operation)
        {
            this.AddOperation(operation);
        }

        public void AddOperation(OperationDescription operation)
        {
            this.targetOperations.Add(operation.Messages[0].Action);
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            if (TargetOperationMatchesRequest(request))
            {
                request = ChangeMessage(request);

                return true;
            }else
            {
                return false;
            }
        }


        public bool TargetOperationMatchesRequest(Message request)
        {
            string requestAction = request.Headers.To.AbsolutePath;
            requestAction =  requestAction.Substring(requestAction.LastIndexOf("/"));

            string targetOperation = "";
            foreach (string targetOperationPath in targetOperations)
            {
                targetOperation = targetOperationPath.Substring(targetOperationPath.LastIndexOf("/"));
                if (targetOperation.Equals(requestAction))
                {
                    return true;
                }
            }
            return false;
        }


        public Message ChangeMessage(Message oldMessage)
        {
            Message newMessage = request.CreateBufferedCopy(Int32.MaxValue).CreateMessage();
            //Change your message

            return newMessage;

        }


        public void BeforeSendReply(ref Message reply, object correlationState)
        {
        }
    }

OPERATION

public class MyOperation : Attribute, IOperationBehavior
    {
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {

            MyMessageInspector inspector = dispatchOperation.Parent.MessageInspectors
                .Where(x => x is MyMessageInspector)
                .FirstOrDefault() as MyMessageInspector;

            if (inspector != null)
            {
                inspector.AddOperation(operationDescription);
            }
            else
            {
                inspector = new MessageInspectors(operationDescription);
                dispatchOperation.Parent.MessageInspectors.Add(inspector);
            }
        }

        public void Validate(OperationDescription operationDescription)
        {
        }
    }

CONTRACT

[ServiceContract]
public interface IService
{
    [OperationContract]
    [MyOperation]
    OutputData MyMethod(InputData inputData);
}

SERVICE

    public class Service : IService
    {
            [WebInvoke(Method = "POST", UriTemplate = "/json/MyMethod", RequestFormat = WebMessageFormat.Json,  ResponseFormat = WebMessageFormat.Json)]
            public OutputData MyMethod(InputData inputData)
            {
               //Implementation
               return new OutputData();

            }
    }
Nelssen
  • 1,023
  • 1
  • 17
  • 42