C# 从异步WCF调用的消息检查器访问HttpContext.Current

C# 从异步WCF调用的消息检查器访问HttpContext.Current,c#,wcf,asp.net-mvc-5,async-await,httpcontext,C#,Wcf,Asp.net Mvc 5,Async Await,Httpcontext,序言:在我们的应用程序中,我们有一些基于自定义消息检查器的逻辑。它通过HttpContext.current 情况:在切换到异步WCF调用后,我们失去了对当前上下文的访问,当前上下文现在是null。我知道当Wait执行他的任务时,上下文实际上被保存,线程被破坏,但也许有一种方法可以用更少的血液和不使用危险的技术来解决这个问题 Upd:这里有一些代码。同步版本: public ActionResult Task() { //some logic var result = ourService.Do

序言:在我们的应用程序中,我们有一些基于自定义消息检查器的逻辑。它通过
HttpContext.current

情况:在切换到异步WCF调用后,我们失去了对当前上下文的访问,当前上下文现在是
null
。我知道当Wait执行他的任务时,上下文实际上被保存,线程被破坏,但也许有一种方法可以用更少的血液和不使用危险的技术来解决这个问题

Upd:这里有一些代码。同步版本:

public ActionResult Task()
{
//some logic
var result = ourService.DoCall();
//some logic
}
//in WCF message inspector
public void AfterReceiveReply(ref Message reply, object correlationState)
{
var request = HttpContext.Current; //got context here
}
异步版本:

public async Task<ActionResult> Task()
{
//some logic
var result = await ourService.DoCallAsync();
//some logic
}
//in WCF message inspector
public void AfterReceiveReply(ref Message reply, object correlationState)
{
var request = HttpContext.Current; //got null
}
公共异步任务()
{
//一些逻辑
var result=await-ourService.DoCallAsync();
//一些逻辑
}
//在WCF消息检查器中
接收后公共无效(参考消息回复,对象关联状态)
{
var request=HttpContext.Current;//得到null
}

关于WCF的一点注意事项,当托管在ASP.NET站点中运行的WCF服务时,您需要启用AspnetCompatibility模式,这可以在Wen.config中完成

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
您可以从页面中查看详细信息,这将为您提供有关模式的更多信息。启用该模式将使WCF在ASP.NET管道下运行,而不是创建模块来连接管道的事件,这还将允许您访问HttpContext对象,否则,如果未启用该设置,该对象将为null

引用文章中的qoute:

HttpContext:Current在从WCF中访问时始终为空 服务改用RequestContext


RequestContext的值可以为null。因为 请求上下文是将请求链接到答复,这没有意义 当您没有回复时有一个请求上下文,在本例中也是如此 如果上下文设置为空。用于在顶部进行单向操作 请求/应答模式,服务器接收请求但不发送 将响应返回给客户端。因此,如果RequestContext为null 意外的是,首先检查操作合同是否为IsOneWay

在标头上指定单向响应时,请求上下文为null

RequestContext可以通过使用

rcontext = operationContext.RequestContext

关于WCF的一点注意事项是,当托管在ASP.NET站点中运行的WCF服务时,您需要启用AspnetCompatibility模式,这可以在Wen.config中完成

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
您可以从页面中查看详细信息,这将为您提供有关模式的更多信息。启用该模式将使WCF在ASP.NET管道下运行,而不是创建模块来连接管道的事件,这还将允许您访问HttpContext对象,否则,如果未启用该设置,该对象将为null

引用文章中的qoute:

HttpContext:Current在从WCF中访问时始终为空 服务改用RequestContext


RequestContext的值可以为null。因为 请求上下文是将请求链接到答复,这没有意义 当您没有回复时有一个请求上下文,在本例中也是如此 如果上下文设置为空。用于在顶部进行单向操作 请求/应答模式,服务器接收请求但不发送 将响应返回给客户端。因此,如果RequestContext为null 意外的是,首先检查操作合同是否为IsOneWay

在标头上指定单向响应时,请求上下文为null

RequestContext可以通过使用

rcontext = operationContext.RequestContext

您可以使用async/await来维护上下文。通常这意味着当您必须保持同步上下文感知时,不要使用
ConfigureAwait(false)
。你在用那个吗?您是否滥用了async与
Task.Run()
?否。没有滥用,没有
任务。运行
,没有
配置等待(false)
。就在我将MVC操作转换为async(以及内部的WCF调用)时,
HttpContext.Current
上的消息检查器将变为null。您可以使用async/await来维护上下文。通常这意味着当您必须保持同步上下文感知时,不要使用
ConfigureAwait(false)
。你在用那个吗?您是否滥用了async与
Task.Run()
?否。没有滥用,没有
任务。运行
,没有
配置等待(false)
。就在我将MVC操作转换为async(以及内部的WCF调用)时,
HttpContext.Current
上的消息检查器变为null。此ASP.NET站点中没有托管此服务,它在另一台计算机上运行。甚至RequestContext也有一个问题——我们的消息检查器中没有它。HttpContext.Current仅在非异步方法上可用,在异步情况下,它是inspector内部的
null
。或者您是指其他内容吗?如果HttpContext未托管在IIS中,并且启用了ASP.NET兼容性,则HttpContext将始终为空。该服务托管在另一台计算机中的何处?该服务未托管在此ASP.NET站点中,它运行在另一台计算机上。甚至RequestContext也有一个问题——我们的消息检查器中没有它。HttpContext.Current仅在非异步方法上可用,在异步情况下,它是inspector内部的
null
。或者您的意思是其他吗?如果HttpContext未托管在IIS中,并且启用了ASP.NET兼容性,则HttpContext将始终为空。该服务托管在另一台计算机的何处?