Silverlight - WCF在localhost上获取clientaccesspolicy

时间:2011-02-07 12:04:24

标签: silverlight wcf localhost service-reference

我有一个Silverlight应用程序,它使用WCF与服务器进行通信。 Silverlight和WCF都在本地计算机(localhost)上运行。当Silverlight调用服务时,它失败并出现通信异常。 我理解这是因为我没有clientaccesspolicy文件,但由于WCF端点在http://localhost:port上运行,我定义了一个接口IPolicyRetriver,并在服务中添加了一个实现,该实现在流中返回clientaccesspolicy

我的问题是,我需要配置什么才能运行而不会出现问题?我知道我必须更改或添加一些内容到我的ServiceReference.ClientConfig文件,但我不明白。我在下面包含了我的ServiceReference.ClientConfig。请让我知道要更改或添加的内容,以及Silverlight中添加此代码的位置。 请不要在此粘贴任何链接来帮助我,因为我在过去两天内打开了所有可能的链接 - 但仍然不明白。

<configuration>
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IMapService" maxBufferSize="2147483647"
                maxReceivedMessageSize="2147483647">
                <security mode="None" />
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="../MapService.svc" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_IMapService" contract="MapService.IMapService"
            name="BasicHttpBinding_IMapService" />
    </client>
</system.serviceModel>

请帮助我!

2 个答案:

答案 0 :(得分:1)

您尚未提及您提及的IPolicyRetriever实现,但此处是您可以使用的示例。

接口规范:

[ServiceContract]
public interface IPolicyRetriever
{
    [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
    Stream GetSilverlightPolicy();

    //[OperationContract, WebGet(UriTemplate = "/crossdomain.xml")]
    //Stream GetFlashPolicy();
}

接口的实现:

    // IPolicyRetriever implementation
    private Stream StringToStream(string result)
    {
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return new MemoryStream(Encoding.UTF8.GetBytes(result));
    }

    public Stream GetSilverlightPolicy()
    {
        string result = @"<?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 StringToStream(result);
     }

然后,您可以在服务器的配置XML文件中包含以下内容。这需要在服务器端,而不是在客户端。我正在强调这一点,因为你在问题中包含了上面的客户端配置。

<behaviors>
  <endpointBehaviors>
    <behavior name="WebHttpNewBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  ...
</behaviors>
<services>
  <service behaviorConfiguration="NewBehavior">
    <endpoint behaviorConfiguration="WebHttpNewBehavior" binding="webHttpBinding"
                bindingConfiguration="" name="PolicyEndpoint" contract="WCFService.IPolicyRetriever" />
    ...
  </service>
</services>

或者,如果您决定以编程方式创建主机(这是我的方式,而不是使用ClientConfig文件,因此上面的示例可能不是100%正确):

ServiceHost host = new ServiceHost(serviceType);
host.AddServiceEndpoint(typeof(IPolicyRetriever), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());

我知道您要求不提供链接,但我使用http://blogs.msdn.com/b/asiatech/archive/2010/05/07/how-to-consume-a-self-hosted-wcf-service-in-a-cross-domain-environment-by-silverlight-client.aspx作为参考来刷新内存,因为我此时无法访问我的Silverlight / WCF项目。

答案 1 :(得分:0)

您不需要使用服务配置或代码进行任何更改。将clientaccesspolicy.xml放在服务网站的ROOT中。如果您使用的是Visual Studio,则可能需要进行属性更改才能使其正常工作。 Silverlight将查找文件的存在。我可能会帮助您使用像Fiddler这样的工具来查看Silverlight在哪里查找文件。

我发现有一个链接非常有用,但由于您不需要任何链接,我不会提供。