跨域错误Silverlight + WCF

时间:2017-03-02 15:38:26

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

我已经阅读了大多数涉及跨域错误的主题,但仍无法使其正常运行。在网站中,我加载了与WCF Webservice通信的Silverlight模块。在localhost上,它工作正常,没有发生错误。

我在http://localhost:50283上托管了Webservice,并在端口50283所指的同一文件夹中找到了 clientaccesspolicy.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,但无论如何都没有带来任何影响。我可以在同一网络中的本地和另一台计算机上访问 clientaccesspolicy.xml http://computerIP:50283/clientaccesspolicy.xml显示内容)。我试图拦截错误,以便找出有关错误性质的更多细节,但是fiddler不会出现任何错误,唯一的浏览器就是这样。从字面上看,我尝试了一切,但仍然没有改变。有没有人遇到类似的问题,可以提供一些我应该寻求解决方案的提示?

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

2 个答案:

答案 0 :(得分:3)

我记得很多年前遇到这种情况并且解决方法有点不同,即行为。请考虑以下事项:

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的服务声明具有绑定。

注册行为:

<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>

将行为添加到绑定(此处为名为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 "/>

答案 1 :(得分:1)

不确定是否必须对它做任何事情,但我有类似的设置,而我的clientaccesspolicy.xml看起来有点不同。

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction">
        <domain uri="http://*"/>
        <domain uri="https://*" />
      </allow-from>
      <grant-to>
        <resource include-subpaths="true" path="/"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

特别是http和https地址的分割是不同的。 除此之外,您尝试使用非默认端口执行此操作,您是否在默认端口80上尝试过它?哦,在生产环境中,这些*被替换为实际的域名。