WCF自托管服务POST请求CORS错误排查求助
WCF自托管服务POST请求CORS错误排查求助
我开发了一个WCF自托管服务,用于与本地连接的打印机通信以打印工牌。浏览器端应用调用该本地服务执行打印操作,所有GET请求均可正常运行,但POST请求始终触发CORS错误,且预请求(Pre-Flight)状态正常。
请求情况说明
GET请求(运行正常)

POST请求(触发CORS错误,预请求正常)


相关C#代码
服务启动代码
private void startService_HTTPS(System.Diagnostics.EventLog eventLog) { eventLog.WriteEntry("Begin startService......."); string serviceUrl = Config.protocol_https + "://" + Config.host + ":" + Config.portNumber_https; WebServiceHost webServiceHost = new WebServiceHost(typeof(Service), new Uri(serviceUrl)); try { ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; KeyedByTypeCollection<IServiceBehavior> behaviors = webServiceHost.Description.Behaviors; ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior() { HttpGetEnabled = false, HttpsGetEnabled = true }; behaviors.Add(serviceMetadataBehavior); ServiceDebugBehavior serviceDebugBehavior = webServiceHost.Description.Behaviors.Find<ServiceDebugBehavior>(); if (serviceDebugBehavior == null) { webServiceHost.Description.Behaviors.Add(new ServiceDebugBehavior() { IncludeExceptionDetailInFaults = true }); } else { serviceDebugBehavior.IncludeExceptionDetailInFaults = true; } WebHttpBinding webHttpBinding = new WebHttpBinding(WebHttpSecurityMode.Transport) { HostNameComparisonMode = HostNameComparisonMode.Exact, MaxReceivedMessageSize = (long)2147483647, TransferMode = TransferMode.Streamed, // CrossDomainScriptAccessEnabled = true }; ServiceEndpoint serviceEndpoint = webServiceHost.AddServiceEndpoint(typeof(IService), webHttpBinding, serviceUrl); serviceEndpoint.Behaviors.Add(new WebHttpBehavior()); serviceEndpoint.Behaviors.Add(new EnableCrossOriginResourceSharingBehavior()); webServiceHost.Open(); eventLog.WriteEntry("Started HTTPS services successfully......"+serviceUrl); // CertManager certs = new CertManager(); // certs.setupCerts(eventLog); } catch (CommunicationException cex) { Console.WriteLine("An exception occurred: {0}", cex.Message); eventLog.WriteEntry("Exception "+cex.Message); eventLog.WriteEntry(cex.StackTrace); webServiceHost.Abort(); } }
自定义CORS行为代码
public class EnableCrossOriginResourceSharingBehavior : BehaviorExtensionElement, IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) { 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"); endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(requiredHeaders)); } public void Validate(ServiceEndpoint endpoint) { } public override Type BehaviorType { get { return typeof(EnableCrossOriginResourceSharingBehavior); } } protected override object CreateBehavior() { return new EnableCrossOriginResourceSharingBehavior(); } }
自定义消息检查器代码
public class CustomHeaderMessageInspector : IDispatchMessageInspector { private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); Dictionary<string, string> requiredHeaders; public CustomHeaderMessageInspector(Dictionary<string, string> headers) { requiredHeaders = headers ?? new Dictionary<string, string>(); } public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) { return null; } public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { var httpHeader = reply.Properties["httpResponse"] as System.ServiceModel.Channels.HttpResponseMessageProperty; httpHeader.StatusCode = System.Net.HttpStatusCode.OK; foreach (var item in requiredHeaders) { log.Debug("BeforeSendReply add header " + item.Key + ", val " + item.Value); httpHeader.Headers.Add(item.Key, item.Value); } } }
我已尝试为服务添加自定义CORS行为,但问题仍未解决,在此寻求技术帮助以排查并解决该问题。
内容的提问来源于stack exchange,提问作者user2872741
相关产品推荐
相关产品推荐

