加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 作为Windows服务托管的c#WCF Restful Web服务的跨源

发布时间:2020-12-15 19:26:35 所属栏目:asp.Net 来源:网络整理
导读:我有一个WCF Restful服务,我作为 Windows服务托管.我想为我的服务添加跨域支持.但是,当我使用global.asax文件时,我可以轻松地做到这一点.但我想将我的服务作为Windows服务托管. 我创建了一个项目,将我的服务托管为Windows服务.现在我面临的问题是,我现在无法
我有一个WCF Restful服务,我作为 Windows服务托管.我想为我的服务添加跨域支持.但是,当我使用global.asax文件时,我可以轻松地做到这一点.但我想将我的服务作为Windows服务托管.

我创建了一个项目,将我的服务托管为Windows服务.现在我面临的问题是,我现在无法添加跨域支持.我尝试了通过app.config文件找到的所有可能的解决方案,但都没有.我在这些链接上尝试了解决方案:

dotnet tricks

enable-cors.org

我尝试使用以下函数在代码中设置标题,方法是在每个服务契约方法中调用它.

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","*");

我想要做的就是为我的Web服务添加CORS支持.如果我做得对,请告诉我.或者还有其他方法可以做同样的事情.

解决方法

终于找到了我的查询解决方案.

一切都在这里. 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());

谢谢大家帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读