【问题标题】:WCF Windows Service installed by ProjectInstaller not working on POST requestProjectInstaller 安装的 WCF Windows 服务无法处理 POST 请求
【发布时间】:2020-11-05 11:48:09
【问题描述】:

我有一个 WCF C# Rest API 应用程序,主要希望可以通过 HTTP 访问以通过设备执行扫描文档。我已经配置了 CORS 并使用 ProjectInstaller 来生成应该用于安装为 Windows 服务的包。当我在没有 ProjectInstaller 功能的开发模式下运行此应用程序时,一切正常。当我尝试执行扫描操作时,问题就出现了 - 然后 CORS 选项请求失败。这很好奇,特别是因为检查扫描仪可用性的 GET 方法在执行时没有任何 CORS 问题。我尝试了多种差异来解决这个问题,从谷歌搜索结果中应用了 CORS 实现并且它有效,但仅限于开发模式。最后我使用了WebHttpBehaviorExtensions,但问题仍然存在。

清除 - ProjectInstaller 嵌入在与 WCF 应用程序链接的 ConsoleApplication 中。

我的 app.config 是 here

我的合同如下:

    [ServiceContract]
public interface IScanService
{
    [OperationContract]
    [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, 
        RequestFormat = WebMessageFormat.Json, UriTemplate = "ScanDocument")]
    Task ScanDocument(int userId, Guid caseId, string fileName);

    [OperationContract]
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
        RequestFormat = WebMessageFormat.Json, UriTemplate = "IsAlive")]
    bool IsAlive();
}

我应该怎么做才能允许在启用 CORS 的情况下发送 POST 请求?

提前感谢您的任何回复。

【问题讨论】:

    标签: c# wcf windows-services rest


    【解决方案1】:

    在你的配置文件中,我看到你使用crossDomainScriptAccessEnabled来解决跨域。如果用它来解决跨域,WCF服务只支持Jsonp访问,都只支持GET请求。

    如果您的服务托管在 IIS 中,您可以在项目中添加 Global.asax,并在 Global.asax 中添加以下代码:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    
        {
           HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "*");
    
          HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
    
          HttpContext.Current.Response.End();
        }
    
    }
    

    当 WCF 托管在 IIS 中时,IIS 会将其视为 Web 服务,因此 Global.asax 中的配置将生效。

    如果你使用自托管,你可以实现 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", "*");
            }
        }
    

    将 ServerMessageLogger 添加到服务行为中:

        [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false)]
        public class CustContractBehaviorAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
        {
            public Type TargetContract => throw new NotImplementedException();
    
            public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
            {
                return;
            }
    
            public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
               return;
            }
    
            public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
            {
                dispatchRuntime.MessageInspectors.Add(new ServerMessageLogger());
            }
    
            public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
            {
                return;
            }
        }
    

    最后,我们需要将此行为应用于服务以支持跨域:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多