我有一个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。