为啥我在 Global.asax.cs 中的 Application_BeginRequest 没有被自托管的 WCF 服务调用
Posted
技术标签:
【中文标题】为啥我在 Global.asax.cs 中的 Application_BeginRequest 没有被自托管的 WCF 服务调用【英文标题】:Why is my Application_BeginRequest in Global.asax.cs not getting called with a self hosted WCF service为什么我在 Global.asax.cs 中的 Application_BeginRequest 没有被自托管的 WCF 服务调用 【发布时间】:2020-10-21 00:19:58 【问题描述】:我正在自行托管需要支持入站 CORS REST 流量的 WCF 服务。所以我添加了带有以下代码块的 Global.asax.cs 文件,但 Application_BeginRequest() 永远不会触发。我也在我的 app.Config 中设置了。还有什么我需要做的吗?这适用于自托管服务还是仅通过 IIS 托管的服务?
protected void Application_BeginRequest(object sender, EventArgs e)
string origin = HttpContext.Current.Request.Headers["origin"];
if (!String.IsNullOrEmpty(origin)) // CORS origin?
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
if (HttpContext.Current.Request.HttpMethod == "OPTIONS") // CORS origin w/ options?
var requestedHeaders = HttpContext.Current.Request.Headers["Access-Control-Request-Headers"];
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", requestedHeaders);
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.StatusCode = 200;
HttpContext.Current.Response.End();
【问题讨论】:
【参考方案1】:只有托管在 IIS 上的全局文件才会生效。 IIS 将 WCF 服务视为 Web 服务来解析其全局文件。如果是自托管的,全局文件将不会被解析和运行。
我们可以让WCF支持JSONP来解决跨域问题:
<binding name="bind1" crossDomainScriptAccessEnabled="true">
</binding>
你也可以实现IDispatchMessageInspector,在服务响应之前添加响应头。这个方案适合自托管。
public class ServerMessageLogger : IDispatchMessageInspector
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
return null;
public void BeforeSendReply(ref Message reply, object correlationState)
WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
有关IDispatchMessageInspector的更多信息,请参考以下链接:
https://docs.microsoft.com/en-us/dotnet/api/system.servicemodel.dispatcher.idispatchmessageinspector?view=netframework-4.8
如果还不清楚,可以参考下面的链接,里面有完整的代码:
How to enable Cross-Origin Resource Sharing in .Net Console Application WCF Service?
更新
以下图片是我的demo:
上面两张图有一张使用了WebOperationContext,一张没有使用。
实际上,WebOperationContext 和 HttpContext 类似。 WebOperationContext 通常用于 WCF REST 方法中,HttpContext 通常用于 ASP.NET WebForms 页面或 ASMX Web Service Web 方法中。
【讨论】:
感谢您的帮助。在绑定中添加 crossDomainScriptAccessEnabled='true' 失败并抛出无法识别的属性 'crossDomainScriptAccessEnabled',因此不起作用。所以我实现了 IDispatchMessageInspector 方法。有没有好方法来测试服务在请求“选项”时报告正确的响应标头?我试过test-cors.org,但是当IDispatchMessageInspector返回响应头时它报告XHR状态:0 XHR状态文本:“”,也许没关系。不确定。现在只需要一种方法来验证服务是否支持 CORS 模式。 在我的更新中,我验证了此解决方案支持 CORS。 实现IDispatchMessageInspector接口后,我们需要将其应用到服务中。详情可以参考我给的第二个链接。以上是关于为啥我在 Global.asax.cs 中的 Application_BeginRequest 没有被自托管的 WCF 服务调用的主要内容,如果未能解决你的问题,请参考以下文章
MVC 应用程序 - 从 Global.asax.cs 检索 LoaderExceptions
Global.asax.cs 为 /.aspx 执行子请求时出错。 Server.Transfer
ASP.NET MVC:如何在 Global.asax.cs 中的 Application_Start() 中检测浏览器宽度