在方法调用之前模拟 C# 类中运行触发器的 WCF 行为



我有一个WCF服务,具有自定义属性在方法调用之前做某事。

属性类:

   /// <summary>
   /// Indica que un método va a ejecutar la validación del token antes de ejecutarse
   /// </summary>
   public class TokenValidationRequiredAttribute : ValidationRequiredAttribute
   {
      /// <summary>
      /// Crear un nuevo Invoker personalizado para la validación del token
      /// </summary>
      /// <param name="operationDescription"></param>
      /// <param name="dispatchOperation"></param>
      public override void ApplyDispatchBehavior (OperationDescription operationDescription, DispatchOperation dispatchOperation)
      {
         // Se crea un nuevo invocador de la operación que será el encargado de validar el token.
         // Se le pasa el invocador original.
         dispatchOperation.Invoker = new TokenValidationInvoker (operationDescription.Name, dispatchOperation.Invoker);
      }
   }

验证requiredAttribute是一种自定义类继承属性并实现ioperationBehavior。现在,在我的自定义类TokenValidationInvoker中,我覆盖了用于自定义验证的方法。

public override object Invoke (object instance, object[] inputs, out object[] outputs)
      {
         // Se castea la instancia a AppLogic
         var logic = instance as AppLogic;
         // Comprobar que le primera parámetro es un string
         if (inputs.Length > 0 && inputs[0] is string) {
            // Se intenta validar el token
            logic.ValidateToken (inputs[0] as string);
         } else {
            throw new FaultException ("El método no tiene la signatura correcta");
         }
         // Si no se ha lanzado la excepción, se llama al invocador original
         return originalInvoker.Invoke (instance, inputs, out outputs);
      }

这种方法就像魅力一样,如果我用[TokenValidationRequired]装饰了我的服务方法,在执行方法之前,我的验证将被调用。

好吧...我正在尝试实现nlayer架构,我希望将服务逻辑和业务逻辑分开,并在BLL(类库(中进行此验证。

是否可能在星级类库中捕获方法来做类似的事情?

预先感谢

这可以使用消息检查员和端点/合同行为来完成。我只是为了记录WCF消息信息而做到了。

您需要定义消息检查员。这可以单独用于客户代理和服务,也可以按照我的定义。

internal class MessageInspector : IClientMessageInspector, IDispatchMessageInspector
{
private void LogMessage(ref msg, bool request)
{
  Console.WriteLine(string.Format("{0}", received ? "Request" : "Response"));
}
    #region IClientMessageInspector
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        LogMessage(ref reply, false);
    }
    public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
    {
        LogMessage(ref request, true);
        return null;
    }
    #endregion
    //Service message inspection        
    #region IDispatchMessageInspector
    public object AfterReceiveRequest(ref Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
    {
        LogMessage(ref request, true);
        return null;
    }
    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        LogMessage(ref reply, false);
    }
    #endregion
}

终点和合同行为

internal class LoggingBehavior : IEndpointBehavior, IContractBehavior
{
  #region IEndpointBehavior
    void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        ;
    }
    void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new Inspectors.MessageInspector());
    }
    void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    {
        ;
    }
    void IEndpointBehavior.Validate(ServiceEndpoint endpoint)
    {
        ;
    }
    #endregion
    #region IContractBehavior
    void IContractBehavior.AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
        ;
    }
    void IContractBehavior.ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
        ;
    }
    void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.MessageInspectors.Add(new Inspectors.MessageInspector());
    }
    void IContractBehavior.Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
        ;
    }
    #endregion
}

完成了所有这些操作,您将需要修改您的服务和服务客户端。

对于服务,您需要为每个

添加合同行为
ServiceHost newService = new ServiceHost(typeof(YourType));
foreach (var endpoint in newService.Description.Endpoints)
{
  endpoint.Contract.ContractBehaviors.Add(new LoggingBehavior());
}

和您的代理客户(我相信您的创建都很好(

YourTypeClient client = new YourTypeClient();
client.EndpointBehaviors.Add(new Behaviors.LoggingBehavior());

这应该是您需要的一切,并且可以在任何引用的汇编中定义,因为实现仅取决于系统。ServiceModel。

最新更新