gpt4 book ai didi

c# - 如何在控制台服务主机中包含 WCF 自定义 header

转载 作者:太空狗 更新时间:2023-10-30 00:24:36 25 4
gpt4 key购买 nike

在我的 WCF 服务中,我遇到了 405 method not allowed 错误,然后遇到一个帖子,建议在我的 WCF 主机的 Application_BeginRequest 中包含以下内容:

protected void Application_BeginRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers",
"Accept, Content-Type,customHeader");

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods",
"POST,GET,OPTIONS");

HttpContext.Current.Response.AddHeader("Access-Control-Max-Age",
"172800");

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials",
"true");

HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers",
"customHeader");

HttpContext.Current.Response.AddHeader("Content-type",
"application/json");

HttpContext.Current.Response.End();
}
else
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers",
"Accept, Content-Type,customHeader");

HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers",
"customHeader");

HttpContext.Current.Response.AddHeader("Content-type",
"application/json");
}
}

但我正在使用控制台应用程序托管我的服务。

using (ServiceHost sc = new ServiceHost(typeof(DataRetriever)))
{
sc.Open();

foreach (var endPoints in sc.Description.Endpoints)
{
Console.WriteLine(endPoints.Address);
}

Console.ReadKey();
sc.Close();
}

那么如何在控制台应用程序中包含 header 。

最佳答案

在 WCF 中,可以通过 OperationContext 类的实例访问 header ,可通过 OperationContext.Current(可用时)访问。

解决此问题的简单方法是在您的服务方法中简单地使用此属性:

[ServiceContract]
public interface IMyService
{
[OperationContract]
void MyMethod();
}

internal class MyService: IMyService
{
public void MyMethod()
{
Console.WriteLine("My Method");
OperationContext.Current.OutgoingMessageHeaders.Add(MessageHeader.CreateHeader("headerFromMethod", "namespace", "headerFromMethodValue"));
}
}

为了完整起见,用于在控制台应用程序中托管此服务的代码(无需配置)是:

using (var serviceHost = new ServiceHost(typeof(MyService)))
{
var endpoint = serviceHost.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), "http://localhost:9000");

serviceHost.Open();

Console.WriteLine("Open for business");
Console.ReadLine();

serviceHost.Close();
}

.NET 客户端会像这样访问 header :

var channel = ChannelFactory<IMyService>.CreateChannel(new BasicHttpBinding(), new EndpointAddress("http://localhost:9000"));

var contextChannel = channel as IContextChannel;
using (new OperationContextScope(contextChannel))
{
channel.MyMethod();

var incommingHeaders = OperationContext.Current.IncomingMessageHeaders;
var header = incommingHeaders.GetHeader<string>("headerFromMethod", "namespace");
Console.WriteLine("Header from server: " + header);
}

如果你有Fiddler , 您还可以使用此工具查看 header 。

虽然此方法将执行您想要的操作,但您是否想混合业务逻辑(包含在 IMyService 的实现中)和控制“带外”的逻辑是值得怀疑的"附加到邮件的信息。

通过实现 IDispatchMessageInspector 获得更清晰的分离,它允许您拦截服务器上的调用并在消息进出时修改消息:

public 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.Headers.Add(MessageHeader.CreateHeader("header", "namespace", "headervalue"));
}

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){}
}

header 以与以前相同的方式从 .NET 客户端访问。值得注意的是,您可以将信息从 AfterReceiveRequest 方法传递到 BeforeSendReply,因为前一个方法中返回的对象作为 correlationState 传递后者中的参数。如果您返回的 header 取决于传入消息的 header ,这将很有用 - 如您的示例所示。

最后,要在服务上安装此功能,您需要修改托管代码,如下所示:

...
var endpoint = serviceHost.AddServiceEndpoint(typeof(IMyService), new BasicHttpBinding(), "http://localhost:9000");
endpoint.Behaviors.Add(new ServerInterceptor());
serviceHost.Open();
...

我们可以凭借 ServerInterceptor 实现 IEndpointBehavior 来做到这一点

关于c# - 如何在控制台服务主机中包含 WCF 自定义 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23493495/

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