WCF在每个服务方法之前执行一个方法';s呼叫

WCF在每个服务方法之前执行一个方法';s呼叫,wcf,wcf-security,Wcf,Wcf Security,我正在寻找一种对每个请求方法调用执行特定方法(服务器端)的方法 这也用于安全验证,但不仅仅限于此 这不是重复的,因为我们的意思不同,所有相关的答案都有不可用的链接,所以不可能得到正确的答案 (很抱歉,这里没有附加任何代码,本期中没有要指定的代码) 谢谢最好的解决方案是创建WCF自定义行为 以下是如何通过几个简单的步骤实现这一点: 客户端: public class FillHeaderDataBehaviourExtension : BehaviorExtensionElement, IEndp

我正在寻找一种对每个请求方法调用执行特定方法(服务器端)的方法

这也用于安全验证,但不仅仅限于此

这不是重复的,因为我们的意思不同,所有相关的答案都有不可用的链接,所以不可能得到正确的答案

(很抱歉,这里没有附加任何代码,本期中没有要指定的代码)


谢谢

最好的解决方案是创建WCF自定义行为

以下是如何通过几个简单的步骤实现这一点:

客户端:

public class FillHeaderDataBehaviourExtension : BehaviorExtensionElement, IEndpointBehavior
{
    #region BehaviorExtensionElement Implementation
    public override Type BehaviorType
    {
        get
        {
            return typeof(FillHeaderDataBehaviourExtension);
        }
    }
    protected override object CreateBehavior()
    {
        return this;
    }
    #endregion

    #region IServiceBehaviour Implementation
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {

    }
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new MessageInspector());
    }
    #endregion
}

public class MessageInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageHeader header = MessageHeader.CreateHeader("HeaderData", String.Empty, HeaderDataVM.GetInstance().GetBaseInstance());
        request.Headers.Add(header); // There is no need for checking if exist before adding. Every request has it's own headers.

        return null;
    }
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
    }
}
public class ExtractHeadersBehaviourExtension : BehaviorExtensionElement, IServiceBehavior
{
    #region BehaviorExtensionElement Implementation
    public override Type BehaviorType
    {
        get
        {
            return typeof(ExtractHeadersBehaviourExtension);
        }
    }
    protected override object CreateBehavior()
    {
        return this;
    }
    #endregion

    #region IServiceBehavior Implementation
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
        {
            ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
            if (channelDispatcher != null)
            {
                foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                {
                    MessageInspector inspector = new MessageInspector();
                    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
                }
            }
        }
    }
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
    #endregion
}

public class MessageInspector : IDispatchMessageInspector
{
    public void BeforeSendReply(ref Message reply, object correlationState)
    {
    }
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        HeaderData headerData = request.Headers.GetHeader<HeaderData>("HeaderData", String.Empty);

        if(headerData != null)
        {
            OperationContext.Current.IncomingMessageProperties.Add("HeaderData", headerData);
        }

        return null;
    }
}
公共类FillHeaderDataBehaviorExtension:BehaviorExtensionElement,IEndpointBehavior
{
#区域行为ExtensionElement实现
公共重写类型BehaviorType
{
得到
{
返回类型(FillHeaderDataExtension);
}
}
受保护的重写对象CreateBehavior()
{
归还这个;
}
#端区
#区域IServiceBehavious实现
public void AddBindingParameters(ServiceDescription ServiceDescription、ServiceHostBase ServiceHostBase、集合终结点、BindingParameterCollection bindingParameters)
{
}
公共无效ApplyDispatchBehavior(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
}
公共无效验证(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
}
公共void验证(ServiceEndpoint)
{
}
public void AddBindingParameters(ServiceEndpoint端点、BindingParameterCollection bindingParameters)
{
}
公共无效ApplyDispatchBehavior(ServiceEndpoint端点、EndpointDispatcher端点Dispatcher)
{
}
public void ApplyClientBehavior(ServiceEndpoint端点、ClientRuntime ClientRuntime)
{
clientRuntime.ClientMessageInspector.Add(新MessageInspector());
}
#端区
}
公共类MessageInspector:IClientMessageInspector
{
发送请求前的公共对象(参考消息请求,IClientChannel通道)
{
MessageHeader header=MessageHeader.CreateHeader(“HeaderData”,String.Empty,HeaderDataVM.GetInstance().GetBaseInstance());
request.Headers.Add(header);//添加之前不需要检查是否存在。每个请求都有自己的头。
返回null;
}
接收后公共无效(参考消息回复,对象关联状态)
{
}
}
服务器端:

public class FillHeaderDataBehaviourExtension : BehaviorExtensionElement, IEndpointBehavior
{
    #region BehaviorExtensionElement Implementation
    public override Type BehaviorType
    {
        get
        {
            return typeof(FillHeaderDataBehaviourExtension);
        }
    }
    protected override object CreateBehavior()
    {
        return this;
    }
    #endregion

    #region IServiceBehaviour Implementation
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {

    }
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new MessageInspector());
    }
    #endregion
}

public class MessageInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        MessageHeader header = MessageHeader.CreateHeader("HeaderData", String.Empty, HeaderDataVM.GetInstance().GetBaseInstance());
        request.Headers.Add(header); // There is no need for checking if exist before adding. Every request has it's own headers.

        return null;
    }
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
    }
}
public class ExtractHeadersBehaviourExtension : BehaviorExtensionElement, IServiceBehavior
{
    #region BehaviorExtensionElement Implementation
    public override Type BehaviorType
    {
        get
        {
            return typeof(ExtractHeadersBehaviourExtension);
        }
    }
    protected override object CreateBehavior()
    {
        return this;
    }
    #endregion

    #region IServiceBehavior Implementation
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
        {
            ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
            if (channelDispatcher != null)
            {
                foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                {
                    MessageInspector inspector = new MessageInspector();
                    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
                }
            }
        }
    }
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
    #endregion
}

public class MessageInspector : IDispatchMessageInspector
{
    public void BeforeSendReply(ref Message reply, object correlationState)
    {
    }
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        HeaderData headerData = request.Headers.GetHeader<HeaderData>("HeaderData", String.Empty);

        if(headerData != null)
        {
            OperationContext.Current.IncomingMessageProperties.Add("HeaderData", headerData);
        }

        return null;
    }
}
公共类提取器HeadersBehaviorExtension:BehaviorExtensionElement,IServiceBehavior
{
#区域行为ExtensionElement实现
公共重写类型BehaviorType
{
得到
{
返回类型(提取器扩展名);
}
}
受保护的重写对象CreateBehavior()
{
归还这个;
}
#端区
#区域IServiceBehavior实现
public void AddBindingParameters(ServiceDescription ServiceDescription、ServiceHostBase ServiceHostBase、集合终结点、BindingParameterCollection bindingParameters)
{
}
公共无效ApplyDispatchBehavior(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
对于(int i=0;i
最后,不要忘记在app.config文件(客户端和服务器端)中对其进行如下配置:

<behaviors>
  <endpointBehaviors>
    <behavior name="NewBehavior">
      <fillHeaderDataBehaviourExtension/>
    </behavior>
  </endpointBehaviors>
</behaviors>
<bindings>

您还可以通过WCF配置编辑器添加这些行。要这样做,请看答案

编辑:添加以下配置代码行后,应用程序配置中可能会出现错误:

别担心,你的应用程序会运行良好的。这是因为GAC(全局程序集缓存)文件夹不包含此行为(因为它是自定义行为)。您可以通过将此行为手动添加到计算机上的GAC文件夹来修复此问题。 但是,此错误可能会阻止您更新服务引用。如果尝试,您将收到以下错误消息:

所以,当您更新服务引用时,只需注释掉这一行(
)(在客户端和服务器端)

资料来源:&

可能重复的内容可能是重复的,但没有对我有帮助的答案,几乎每个链接都不可用。你能解释一下为什么@Matthieu提到的链接对你没有帮助,所以我们可以提供其他想法吗?这是一种拦截请求的简单方法,您可以在其中执行所需的任何代码。另请参阅: