WCF服务中的操作筛选器

时间:2014-07-25 13:25:43

标签: c# .net wcf

在WCF服务中是否有类似ActionFilterAttribute(来自ASP.NET MVC)的东西(或类似的东西)。基本上我想做的是记录来自我的服务的内容和goint,我不想在每个ServiceContract中编写日志代码。是的,这个问题非常笼统,但你理解我想做的事情。

2 个答案:

答案 0 :(得分:5)

是的,它被称为MessageInspectors / ParameterInspectors,在这里你可以阅读它们 http://msdn.microsoft.com/en-us/library/aa717047%28v=vs.110%29.aspx

这正是您要寻找的,WCF自定义行为日志记录 http://www.codeproject.com/Articles/243352/LoggingBehavior-How-to-Connect-Log-prints-with-the

唯一令人困惑的是,您可以在WCF服务和WCF代理上使用消息检查器,在您的情况下,您只需要服务端

答案 1 :(得分:1)

我必须读很多书才能找到答案,我不是WCF专家,但是鉴于此信息有点稀缺,我正在分享对我有用的东西。

我的解决方案包括使用OperationBehavior和DispatcherMessageInspector

操作行为

  • 允许您更改绑定信息,验证操作 描述,并应用调度程序行为。

DispatcherMessageInspector

  • 允许您检查和更改为您发送的消息 服务。

调度程序

  • 从通信渠道获取消息并发送到 正确的操作,然后将结果返回给调用方。

服务运营

  • 您的服务方式

代码解决方案

消息检查器

+---+---+----------+----------+----------+----------+-------+
|id_|p  |201806    |201807    |201808    | 201809   | 201810|
+---+---+----------+----------+----------+----------+-------+
| 1 | A |         0|        0 |         0|      4   | 26    |
| 2 | B |         9|        19|         0|      0   | 0     |
| 2 | B |         0|        0 |        18|      30  | 7     |
+---+---+----------+----------+----------+----------+-------+

操作

   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)
        {
        }
    }

合同

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)
        {
        }
    }

服务

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