2010-02-24 30 views
4

并对于另一个跨域问题抱歉。与WcfSvcHost交叉领域异常

我一直都在为这一整天而奋斗,现在正处于沸腾的时刻。

我有一个Silverlight应用程序项目(SLApp1),一个用于托管Silverlight(SLApp1.Web)和WCF项目(SLWcfService)的Web项目。

现在我正在一起构建所有项目,所有项目都在一个解决方案中。 Web项目由Visual Studio托管,WCF服务由WcfSvcHost托管。

由于Web和wcf单独托管的问题存在跨域问题,因此每次我的Silverlight应用程序尝试对WCF调用时都会引发跨域异常。

我曾尝试:

  1. 添加clientaccesspolicy.xml到C:\ inetpud \ wwwroot的
  2. 使用的WebHttpBinding和服务有ReadPolicy方法

的问题是我还开发解决方案并发布服务,然后在IIS中托管并不是一个可行的解决方案。

为什么这必须非常困难?

请帮忙!

参考资料:

我的App.config:

 <system.serviceModel> 
    <services> 
     <service name="Test.Service1" behaviorConfiguration="Test.Service1Behavior"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:8055" /> 
      </baseAddresses> 
     </host> 
     <endpoint address="Service1" binding="basicHttpBinding" contract="Test.IService1"/> 
     <endpoint address="" binding="webHttpBinding" behaviorConfiguration="webHttpBehavior" contract="Test.WCFService.IClientAccessPolicy" /> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="Test.WCFService.Service1Behavior"> 
      <serviceMetadata httpGetEnabled="True" /> 
      <serviceDebug includeExceptionDetailInFaults="False" /> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="webHttpBehavior"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    </system.serviceModel> 
+0

我已经在现有项目疲于应付这个问题,以及在过去的几天里,我还有其他的WCF服务使用Silverlight,但由于某种原因,工作我只是不能使这一个工作,很想看到一个解决方案 – Jimmy 2010-02-24 13:57:56

+0

如果我添加一个WCF服务项目到.Web项目,但我的解决方案是不可行的,我可以很容易地得到这个工作,并且有些挫败了拥有WCF项目模板的目的。 – Oliver 2010-02-24 14:08:54

回答

0

好不知何故,我得到它的工作使用REST和的WebHttpBinding伎俩。我对如何从读取的文件中读取clientaccesspolicy以仅使用cons字符串进行了更改。

这里是我解决了这个问题:

的App.config:

<system.serviceModel> 
<services> 
    <service name="Symphony.Server.WCFService.Service1" behaviorConfiguration="Symphony.Server.WCFService.Service1Behavior"> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://localhost:8055" /> 
     </baseAddresses> 
    </host> 
    <endpoint address="Service1" binding="basicHttpBinding" contract="Symphony.Server.WCFService.IService1"/> 
    <endpoint address="" binding="webHttpBinding" behaviorConfiguration="webHttpBehavior" contract="Symphony.Server.WCFService.IClientAccessPolicy" /> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="Symphony.Server.WCFService.Service1Behavior"> 
     <serviceMetadata httpGetEnabled="True" /> 
     <serviceDebug includeExceptionDetailInFaults="False" /> 
    </behavior> 
    </serviceBehaviors> 
    <endpointBehaviors> 
    <behavior name="webHttpBehavior"> 
     <webHttp/> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 

IClientAccessPolicy.cs

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

个Service1.cs

public class Service1 : IService1, IClientAccessPolicy 
{ 
    public IList<string> GetData(string value) 
    { 
     //Some logic 
    } 

    [OperationBehavior] 
    public Stream GetPolicy() 
    { 
     const 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>"; 

     if (WebOperationContext.Current != null) 
      WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml"; 
     return new MemoryStream(Encoding.UTF8.GetBytes(result)); 
    } 

注: 必须包括System.ServiceModel.Web作为参考

感谢您在WCFService项目

0

我也面临着同样的问题一时间前。我得出的结论是,引用WebProject(托管Silverlight控件)中的WCFService项目的dll,并根据WCFService更改其web.config。然后,而不是消费WcfSvcHost引用我从WebProject使用引用,这是我使用的解决方法。

但总之,在由WCFSvcHost托管的服务上应用客户端访问策略有点棘手。

+0

我说实话,说WcfSvcHost是默认的托管机制,但无法处理跨域的事实是相当愚蠢的。 我的解决方案的组织方式很合理,模块化程度很高,但这个问题阻碍了我前进的能力。 – Oliver 2010-02-24 14:36:02

1

尽管我不确定这是否能解决您的问题,但我会告诉您我是如何设法解决类似的解决方案布局问题的,并且这些步骤可能会提供一些指导。

我使用silverlight项目(domainexception),一个web项目(domainexception.Web)和一个wcf服务(WcfServiceLibrary1)建立了一个解决方案。我使Service1端点成为一个基本的HttpBinding,就像它在App.config中一样。

我再添加了一个服务引用Silverlight项目,并将其与以下地址建立它:

http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/

尝试这样我也跑进运行跨域策略问题。

然后,我添加了webHttpBinding和方法,并仍然发现它没有工作。

所以,最后我改变了基地址从一个以上

http://localhost:8731

和它的工作。

最后工作。所以这就是它最终的样子。

的App.config

<system.serviceModel> 
<services> 
    <service name="WcfServiceLibrary1.Service1" behaviorConfiguration="WcfServiceLibrary1.Service1Behavior"> 
    <host> 
     <baseAddresses> 
     <add baseAddress = "http://localhost:8731/" /> 
     </baseAddresses> 
    </host> 
    <endpoint address ="Service" binding="basicHttpBinding" contract="WcfServiceLibrary1.IService1"> 
     <identity> 
     <dns value="localhost"/> 
     </identity> 
    </endpoint> 
    <endpoint address="" binding="webHttpBinding" behaviorConfiguration="policyBehavior" contract="WcfServiceLibrary1.IService1"/> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
    </service> 
</services> 
<behaviors> 
    <endpointBehaviors> 
    <behavior name="policyBehavior"> 
     <webHttp /> 
    </behavior> 
    </endpointBehaviors> 
    <serviceBehaviors> 
    <behavior name="WcfServiceLibrary1.Service1Behavior"> 
     <serviceMetadata httpGetEnabled="True"/> 
     <serviceDebug includeExceptionDetailInFaults="False" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

ServiceReferences.ClientConfig

<configuration> 
<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647" 
       maxReceivedMessageSize="2147483647"> 
       <security mode="None" /> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost:8731/Service" binding="basicHttpBinding" 
      bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" 
      name="BasicHttpBinding_IService1" /> 
    </client> 
</system.serviceModel> 

和我的网页呼吁政策:

接口

[OperationContract, WebGet(UriTemplate="clientaccesspolicy.xml")] 
    Stream ReturnPolicy(); 

代码

public System.IO.Stream ReturnPolicy() 
    { 
     string file = @"<?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 new MemoryStream(Encoding.UTF8.GetBytes(file)); 
    } 
+0

哈哈,我刚发布了一个类似的帖子。非常感谢! – Oliver 2010-02-24 15:16:00

0

PolicyService(REST)可以解决这个万阿英,蒋达清。这种服务允许 在响应中发送xml(clientAccessPolicy)。例如,如果你的服务的URL是这样的: http://localhost:[port]/Design_Time_Addresses/MyService.svc

然后PolicyService网址为: http://localhost:[port]/clientaccesspolicy.xml(这种REST请求将响应发送到clientaccesspolicy SilverlightClient)。

这里是如何创建这样PolicyService链接: http://social.msdn.microsoft.com/Forums/en/wcf/thread/d145a38f-b9bb-4c8e-9eab-b728dacc19df

+0

你能详细说明一下吗? 如果我可以独立使用WebHttpBinding并使GetPolicy()返回clientaccsesspolicy,然后让其他服务可以像平常一样运行,那将是一件好事。 不,我有点困惑,因为我无法运行多个服务器一个端口? 也许你可以给我一个分段结构的例子吗? – Oliver 2010-02-25 12:31:08