wcf - 跨域错误 Silverlight + WCF

标签 wcf silverlight cross-domain cross-domain-policy

我已经阅读了大多数涵盖跨域错误的主题,但仍然无法使其正常工作。在网站中,我加载了与 WCF Webservice 通信的 Silverlight 模块。在本地主机上,它工作正常,没有发生错误。
我在 http://localhost:50283 上托管了 Web 服务在端口 50283 所指的同一文件夹中,我有 客户端访问策略.xml 位于如下所示

<access-policy>
   <cross-domain-access>
     <policy>
       <allow-from http-request-headers="*">
         <domain uri="*"/>
       </allow-from>
       <grant-to>
         <resource path="/" include-subpaths="true"/>
       </grant-to>
    </policy>
   </cross-domain-access>
</access-policy>

我几乎在任何地方都放置了 clientaccesspolicy.XML,包括\wwwroot ,但这无论如何都没有带来任何影响。我可以访问客户端访问策略.xml 在本地和同一网络内的不同计算机上(http://computerIP:50283/clientaccesspolicy.xml 显示内容)。我试图拦截错误以找出有关错误性质的更多详细信息,但 fiddler 没有列出任何错误,唯一的浏览器会这样做。从字面上看,我尝试了一切,但仍然没有改变。有没有人遇到过类似的问题并且可以提供一些我应该寻求解决方案的提示?

我遇到了类似的话题,也没有解决方案,唉
Silverlight-to-WCF cross-domain exception, but clientaccesspolicy.xml is being read successfully

最佳答案

我记得很多年前遇到过这个问题,并以不同的方式解决它,即通过一种行为。考虑以下:

using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.Xml;

internal class CrossDomainServiceBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    private ServiceHost serviceHost;

    public override Type BehaviorType
    {
        get { return typeof(CrossDomainServiceBehavior); }
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        if (serviceHost == null)
        {
            serviceHost = new ServiceHost(typeof(CrossDomainPolicyService));

            string address = new Uri(endpoint.Address.Uri, "/").ToString();
            ServiceEndpoint crossDomainEndpoint = serviceHost.AddServiceEndpoint(typeof(ICrossDomainPolicyService), new WebHttpBinding(), address);
            crossDomainEndpoint.Behaviors.Add(new WebHttpBehavior());

            serviceHost.Open();
        }
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    protected override object CreateBehavior()
    {
        return new CrossDomainServiceBehavior();
    }
}

internal class CrossDomainPolicyService : ICrossDomainPolicyService
{
    public Message ProvideClientAccessPolicyFile()
    {
        XmlReader xmlReader = CreateClientAccessXml();
        return Message.CreateMessage(MessageVersion.None, string.Empty, xmlReader);
    }

    public Message ProvideCrossDomainPolicyFile()
    {
        XmlReader xmlReader = CreateCrossDomainXml();
        return Message.CreateMessage(MessageVersion.None, string.Empty, xmlReader);
    }

    private static XmlReader CreateClientAccessXml()
    {
        TextReader reader = new StringReader(@"<?xml version='1.0' encoding='utf-8'?>
                                                  <access-policy>
                                                    <cross-domain-access>
                                                      <policy>
                                                        <allow-from http-request-headers='*' >
                                                        <domain uri='*'/>
                                                        </allow-from>
                                                        <grant-to>
                                                          <resource path='/' include-subpaths='true'/>
                                                        </grant-to>
                                                      </policy>
                                                    </cross-domain-access>
                                                  </access-policy>");
        return XmlReader.Create(reader);
    }

    private static XmlReader CreateCrossDomainXml()
    {
        TextReader reader = new StringReader(@"<?xml version='1.0'?>
                                                  <cross-domain-policy>
                                                  <allow-http-request-headers-from domain='*' headers='*'/>
                                                  </cross-domain-policy>");
        return XmlReader.Create(reader);
    }
}

CrossDomainServiceBehavior 需要添加到 WCF 服务的行为中,它使用 CrossDomainPolicyService 动态添加跨域策略。这可以防止您将跨域文件添加到网站本身。

从代码中添加行为(例如使用自托管服务):
endPoint.Behaviors.Add(new CrossDomainServiceBehavior());

或者在配置中的 WCF 定义的情况下:
为了这个示例,我将假设 CrossDomainServiceBehavior 位于命名空间 Services.CrossDomainServiceBehavior 中,并且它所在的程序集是具有中性文化的 1.0.0.0 版本。它还假设您的服务声明上有一个名为 webHttp 的绑定(bind)。

注册行为:
<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="CrossDomainServiceBehavior" type="Services.CrossDomainServiceBehavior, CrossDomainServiceBehavior.AssemblyName, Version=1.0.0.0, Culture=neutral" />
    </behaviorExtensions>
  </extensions>

声明行为:
<behaviors>
  <endpointBehaviors>
    <behavior name="CrossDomainServiceBehavior">
      <webHttp/>
      <CrossDomainServiceBehavior/>
    </behavior>
  </endpointBehaviors>
<behaviors>

将行为添加到绑定(bind)中(这里以 webHttp 为例):
<bindings>
    <webHttpBinding>
        <binding name="webHttp"
         maxReceivedMessageSize="20000000" >
            <security mode="None">
                <transport clientCredentialType = "None"/>
            </security>
        </binding>
        <CrossDomainServiceBehavior />
    </webHttpBinding>
</bindings>

最后,将行为添加到您的服务端点,这里是实现 ISomeService 的示例:
<endpoint address="" binding="webHttpBinding" contract="Services.ISomeService" bindingConfiguration="webHttp" behaviorConfiguration="CrossDomainServiceBehavior "/>

关于wcf - 跨域错误 Silverlight + WCF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42559666/

相关文章:

c# - 如何处理在 RichTextBox 中单击超链接的事件

c# - 在 silverlight 和异步回调中保存文件

node.js - Socket.io xdomain https flashsockets

reactjs - Express/React 与 CORS - 为 React SPA 设置仅 HTTP 的安全 Cookie

WCF 句柄更新人员对象

c# - 如何从正在运行的服务中获取 WSDL 文件?

wcf - 向自托管 WCF 服务添加可选的 gzip 压缩

visual-studio-2010 - 为什么VS会生成一个xs :nonNegativeInteger attribute for WCF client?的字符串属性

silverlight - NuGet 无法使用 XmlnsDefinitionAttribute 从程序集中提取元数据

php - 实时混合应用程序没有 'Access-Control-Allow-Origin' 问题