我有一个WCF Restful服务,我作为
Windows服务托管.我想为我的服务添加跨域支持.但是,当我使用global.asax文件时,我可以轻松地做到这一点.但我想将我的服务作为Windows服务托管.
我创建了一个项目,将我的服务托管为Windows服务.现在我面临的问题是,我现在无法添加跨域支持.我尝试了通过app.config文件找到的所有可能的解决方案,但都没有.我在这些链接上尝试了解决方案:
我尝试使用以下函数在代码中设置标题,方法是在每个服务契约方法中调用它.
- private static void SetResponseHeader()
- {
- WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin","*");
- WebOperationContext.Current.OutgoingResponse.Headers.Add("Cache-Control","no-cache,no-store");
- WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Request-Methods","GET,POST,PUT,DELETE,OPTIONS");
- WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers","Content-Type,Accept");
- }
接口:
- namespace ReaderService
- {
- [ServiceContract]
- public interface INFCReader
- {
- [OperationContract]
- [WebInvoke(UriTemplate = "GetLogin",Method = "POST")]
- GetLoginResults GetLogin(DisplayRequest dispRequest);
- }
这里DisplayRequest是一个类.
请帮帮我们如果有人想查看任何其他代码,请告诉我.
非常感谢.
编辑:::::::
非常感谢托马斯的回复.
我创建了一个实现IDispactchMessageInspector的MessageInspector类.我在MessageInspector类中有以下代码.
- public class MessageInspector : IDispatchMessageInspector
- {
- public object AfterReceiveRequest(ref Message request,IClientChannel channel,InstanceContext instanceContext)
- {
- HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*");
- if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
- {
- HttpContext.Current.Response.AddHeader("Cache-Control","no-cache");
- HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods",POST");
- HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers",Accept");
- HttpContext.Current.Response.AddHeader("Access-Control-Max-Age","1728000");
- HttpContext.Current.Response.End();
- }
- return null;
- }
- }
我现在得到的错误是 – ‘对象引用没有设置为对象的实例.’
错误发生在上面代码的这一行
- HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*");
解决方法
终于找到了我的查询解决方案.
一切都在这里. Supporting Cross Origin Resource
一步一步的解释很好.我想我可能从来没有想过这个问题.
码:
创建2个类,如下所示:
> MessageInspector实现IDispatchMessageInspector.
> BehaviorAttribute实现Attribute,IEndpointBehavior和IOperationBehavior.
具有以下细节:
- //MessageInspector Class
- using System;
- using System.ServiceModel;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Dispatcher;
- using System.ServiceModel.Description;
- namespace myCoRSService
- {
- public class MessageInspector : IDispatchMessageInspector
- {
- private ServiceEndpoint _serviceEndpoint;
- public MessageInspector(ServiceEndpoint serviceEndpoint)
- {
- _serviceEndpoint = serviceEndpoint;
- }
- /// <summary>
- /// Called when an inbound message been received
- /// </summary>
- /// <param name="request">The request message.</param>
- /// <param name="channel">The incoming channel.</param>
- /// <param name="instanceContext">The current service instance.</param>
- /// <returns>
- /// The object used to correlate stateMsg.
- /// This object is passed back in the method.
- /// </returns>
- public object AfterReceiveRequest(ref Message request,InstanceContext instanceContext)
- {
- StateMessage stateMsg = null;
- HttpRequestMessageProperty requestProperty = null;
- if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
- {
- requestProperty = request.Properties[HttpRequestMessageProperty.Name]
- as HttpRequestMessageProperty;
- }
- if (requestProperty != null)
- {
- var origin = requestProperty.Headers["Origin"];
- if (!string.IsNullOrEmpty(origin))
- {
- stateMsg = new StateMessage();
- // if a cors options request (preflight) is detected,// we create our own reply message and don't invoke any
- // operation at all.
- if (requestProperty.Method == "OPTIONS")
- {
- stateMsg.Message = Message.CreateMessage(request.Version,null);
- }
- request.Properties.Add("CrossOriginResourceSharingState",stateMsg);
- }
- }
- return stateMsg;
- }
- /// <summary>
- /// Called after the operation has returned but before the reply message
- /// is sent.
- /// </summary>
- /// <param name="reply">The reply message. This value is null if the
- /// operation is one way.</param>
- /// <param name="correlationState">The correlation object returned from
- /// the method.</param>
- public void BeforeSendReply(ref Message reply,object correlationState)
- {
- var stateMsg = correlationState as StateMessage;
- if (stateMsg != null)
- {
- if (stateMsg.Message != null)
- {
- reply = stateMsg.Message;
- }
- HttpResponseMessageProperty responseProperty = null;
- if (reply.Properties.ContainsKey(HttpResponseMessageProperty.Name))
- {
- responseProperty = reply.Properties[HttpResponseMessageProperty.Name]
- as HttpResponseMessageProperty;
- }
- if (responseProperty == null)
- {
- responseProperty = new HttpResponseMessageProperty();
- reply.Properties.Add(HttpResponseMessageProperty.Name,responseProperty);
- }
- // Access-Control-Allow-Origin should be added for all cors responses
- responseProperty.Headers.Set("Access-Control-Allow-Origin","*");
- if (stateMsg.Message != null)
- {
- // the following headers should only be added for OPTIONS requests
- responseProperty.Headers.Set("Access-Control-Allow-Methods","POST,OPTIONS,GET");
- responseProperty.Headers.Set("Access-Control-Allow-Headers",Accept,Authorization,x-requested-with");
- }
- }
- }
- }
- class StateMessage
- {
- public Message Message;
- }
- }
- //BehaviorAttribute Class
- using System;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Description;
- using System.ServiceModel.Dispatcher;
- namespace OpenBetRetail.NFCReaderService
- {
- public class BehaviorAttribute : Attribute,IEndpointBehavior,IOperationBehavior
- {
- public void Validate(ServiceEndpoint endpoint) { }
- public void AddBindingParameters(ServiceEndpoint endpoint,BindingParameterCollection bindingParameters) { }
- /// <summary>
- /// This service modify or extend the service across an endpoint.
- /// </summary>
- /// <param name="endpoint">The endpoint that exposes the contract.</param>
- /// <param name="endpointDispatcher">The endpoint dispatcher to be
- /// modified or extended.</param>
- public void ApplyDispatchBehavior(ServiceEndpoint endpoint,EndpointDispatcher endpointDispatcher)
- {
- // add inspector which detects cross origin requests
- endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
- new MessageInspector(endpoint));
- }
- public void ApplyClientBehavior(ServiceEndpoint endpoint,ClientRuntime clientRuntime) { }
- public void Validate(OperationDescription operationDescription) { }
- public void ApplyDispatchBehavior(OperationDescription operationDescription,DispatchOperation dispatchOperation) { }
- public void ApplyClientBehavior(OperationDescription operationDescription,ClientOperation clientOperation) { }
- public void AddBindingParameters(OperationDescription operationDescription,BindingParameterCollection bindingParameters) { }
- }
- }
在此之后,您需要做的就是将此消息检查器添加到服务端点行为.
- ServiceHost host = new ServiceHost(typeof(myService),_baseAddress);
- foreach (ServiceEndpoint EP in host.Description.Endpoints)
- EP.Behaviors.Add(new BehaviorAttribute());
谢谢大家帮助.