gpt4 book ai didi

c# - WCF 使用 AddressHeader.CreateAddressHeader() 方法添加 header 问题

转载 作者:太空宇宙 更新时间:2023-11-03 12:39:02 25 4
gpt4 key购买 nike

我正在尝试通过 WCF 向每条传出请求消息添加自定义 header 。

我这样创建了 header 对象:

EndpointAddressBuilder eab = new EndpointAddressBuilder(combinedService.Endpoint.Address);
AddressHeader addressHeader = AddressHeader.CreateAddressHeader("HeaderData", String.Empty, "String data");
eab.Headers.Add(addressHeader);
combinedService.Endpoint.Address = eab.ToEndpointAddress();

我在我的代码中的两个位置使用了这个确切的代码,一个工作正常但另一个不工作。问题出在以下代码行中:

AddressHeader addressHeader = AddressHeader.CreateAddressHeader("HeaderData", String.Empty, "String data");

当它工作时(成功传递 header 数据),创建的对象如下所示: enter image description here

但是当它不起作用时,创建的对象看起来像这样: enter image description here

执行此操作的方法完全相同,但两次位置代码调用会产生不同的结果。

我应该在 addressHeader 对象上执行任何方法来强制它序列化该对象吗?也许是这样的:Flush()?

我知道我可以使用几种众所周知的模式来添加自定义 header ,例如:“自定义行为”、“客户端消息检查器”等...但是我需要在发送之前将其添加到特定点消息。

最佳答案

我终于找到了解决方案。

我只是按照 this 中的步骤操作和 this优秀、详细、简单的文章。

虽然这段代码可能看起来又长又复杂,但这是在 WCF 中处理 header 数据的最正确方式。所以这最终是值得的。

您只需配置自定义行为来处理 WCF header 。

事情是这样的:

客户端:

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;
}
}

最后,不要忘记在 app.config 文件(客户端和服务器端)中配置它,如下所示:

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

您还可以通过 WCF 配置编辑器添加这些行。为此,请查看 this回答。

重要:请注意,添加这些行配置代码后,您将在应用配置中收到错误消息:

enter image description here

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

enter image description here

因此,当您更新服务引用时,只需注释掉这一行 ( <extractHeadersBehaviourExtension/>)(在客户端和服务器端)。

关于c# - WCF 使用 AddressHeader.CreateAddressHeader() 方法添加 header 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39773448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com