c# - WCF 主机将自定义 HTTP 标头添加到响应
问题描述
我有一个作为 Windows 服务运行的独立 C# WCF 服务。我需要在所有响应中添加自定义标头,例如X-Frame-Options 。我试图将以下类的实例添加到ServiceEndpoint.Behaviors
internal class ServerInterceptor : IDispatchMessageInspector, IEndpointBehavior
{
object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState)
{
reply.Properties.Add("X-Frame-Options", "deny");
}
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
}
void IEndpointBehavior.Validate(ServiceEndpoint endpoint) { }
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }
}
这不会向响应中添加任何 HTTP 标头,尽管该类被调用,因为调试器可以单步执行该BeforeSendReply
函数。此外,如果我替换reply.Properties
为,reply.Headers
则添加标头,但不是添加到 HTTP 标头,而是添加到 SOAP 标头。
如何将X-Frame-Options之类的 HTTP 标头添加到响应中?
解决方案
我做了一个示例,用于添加额外的 CORS HTTP 标头,希望它对您有所帮助。
消息检查器。
public class CustomHeaderMessageInspector : IDispatchMessageInspector
{
Dictionary<string, string> requiredHeaders;
public CustomHeaderMessageInspector(Dictionary<string, string> headers)
{
requiredHeaders = headers ?? new Dictionary<string, string>();
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
string displayText = $"Server has received the following message:\n{request}\n";
Console.WriteLine(displayText);
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
if (!reply.Properties.ContainsKey("httpResponse"))
reply.Properties.Add("httpResponse", new HttpResponseMessageProperty());
var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
foreach (var item in requiredHeaders)
{
httpHeader.Headers.Add(item.Key, item.Value);
}
string displayText = $"Server has replied the following message:\n{reply}\n";
Console.WriteLine(displayText);
}
}
自定义合同属性。
public class MyBehaviorAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
{
public Type TargetContract => typeof(MyBehaviorAttribute);
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
var requiredHeaders = new Dictionary<string, string>();
requiredHeaders.Add("Access-Control-Allow-Origin", "*");
requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
requiredHeaders.Add("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
dispatchRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(requiredHeaders));
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
}
应用契约行为。
[ServiceContract(Namespace = "mydomain")]
[MyBehavior]
public interface IService
{
[OperationContract]
[WebGet]
string SayHello();
}
如果有什么我可以帮忙的,请随时告诉我。
推荐阅读
- python - 如何修复“AttributeError:'RDD'对象没有属性'rfind'”?
- azure - 如何在 Azure Devops 中为多模块 maven 创建构建管道
- salesforce - 从自定义按钮调用 Apex 方法
- google-sheets - 具有动态日期范围的 Sumifs 公式在谷歌表中不起作用
- ruby-on-rails - Prawn PDF 只为当前用户生成记录
- docker - docker-compose.yml 用于 elasticsearch 7.0.1 和 kibana 7.0.1
- c++ - 如何构造一个可以替换子类然后泛型调用的模板类类型?
- haskell - 如何在 IO 中采样 RVarT
- wordpress - 当 Stripe 在 WooCommerce 中出现错误时触发函数
- r - 当我使用 dplyr::filter 和序列命令时,它会随机跳过不应该的行