gpt4 book ai didi

asp.net - 作为 Windows 服务托管的 c# WCF Restful Web 服务的跨源资源共享

转载 作者:行者123 更新时间:2023-12-02 17:09:11 25 4
gpt4 key购买 nike

我有一个 WCF Restful 服务,我将其作为 Windows 服务托管。我想为我的服务添加跨域支持。但是,当我使用 global.asax 文件时,我可以轻松地做到这一点。但我想将我的服务托管为 Windows 服务。

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

dotnet tricks

enable-cors.org

我尝试通过在每个服务契约(Contract)方法中调用以下函数来设置代码中的 header 。

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 是一个类。

请大家帮忙。如果有人想查看任何其他代码,请告诉我。

非常感谢。

编辑:::::::

非常感谢托马斯的回复。我创建了一个实现 IDispatchMessageInspector 的 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", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
return null;
}
}

我现在收到的错误是——“对象引用未设置为对象的实例。”错误就在上面代码的这一行

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

我想做的就是向我的网络服务添加 CORS 支持。如果我做得正确,请告诉我。或者有没有其他方法可以做到同样的事情。

最佳答案

终于找到了解决我的疑问的方法。

一切都在这里。 Supporting Cross Origin Resource

很好的逐步解释。我想我自己永远无法解决这个问题。

代码:

创建 2 个类,如下所示:

  1. MessageInspector 实现 IDispatchMessageInspector
  2. BehaviorAttribute 实现 AttributeIEndpointBehaviorIOperationBehavior

包含以下详细信息:

//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,
IClientChannel channel,
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",
"Content-Type, 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());

谢谢大家的帮助。

关于asp.net - 作为 Windows 服务托管的 c# WCF Restful Web 服务的跨源资源共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16024347/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com