【问题标题】:Cannot access self hosted wcf service in silverlight application无法在 silverlight 应用程序中访问自托管 wcf 服务
【发布时间】:2012-09-11 16:37:47
【问题描述】:

我正在尝试从我的 Silverlight 应用程序中访问自托管 WCF 服务,但它无法正常工作。该服务配置为使用 SSL,我可以使用 WCFTestClient 工具、Web 浏览器来访问它,我可以引用该服务并从 silverlight 项目中更新它。问题是当 silverlight 应用程序尝试调用服务时,它会出现以下错误:

服务器没有提供有意义的回复;这可能是由于合同不匹配、会话过早关闭或内部服务器错误造成的。

当我使用 WCF 测试客户端工具点击它时,它返回的数据没有问题(如预期的那样)。

有什么想法吗?

以下是我的应用配置:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttp" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="6553600" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <security mode="Transport">
          </security>
        </binding>
      </basicHttpBinding>
      <webHttpBinding>
        <binding name="webHttp" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="6553600" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <security mode="Transport">
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
      <service name="Application.ServiceModel.ApplicationService" behaviorConfiguration="serviceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="https://192.168.1.171:8000/ApplicationServiceModel/service"/>
          </baseAddresses>
        </host>
        <endpoint address="" 
                  binding="basicHttpBinding" 
                  bindingConfiguration="basicHttp" 
                  contract="Application.ServiceModel.IApplicationService"  />
        <endpoint address="mex" 
                  binding="mexHttpsBinding" 
                  contract="IMetadataExchange"/>
        <endpoint address="http://localhost:8000/"
                  binding="webHttpBinding"
                  contract="Application.ServiceModel.IApplicationService"
                  behaviorConfiguration="webHttpBehavior" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceBehavior">
          <serviceMetadata httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

【问题讨论】:

    标签: c# wcf silverlight service


    【解决方案1】:

    @carlos:您的代码非常适合 http。但是,我无法让它适用于 https。我只是得到 "clientaccesspolicy.xml" is not found...

    我对主函数做了这些修改:

                    public static void Main()
            {
                string baseAddress = "https://" + Environment.MachineName + ":8000";
                ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
                BasicHttpBinding basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                host.AddServiceEndpoint(typeof(ITest), basicHttpBinding, "basic");
                WebHttpBinding webHttpBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
                HttpTransportSecurity httpTransportSecurity = webHttpBinding.Security.Transport;
                httpTransportSecurity.ClientCredentialType = HttpClientCredentialType.None;
                httpTransportSecurity.ProxyCredentialType = HttpProxyCredentialType.None;
                WebHttpBehavior webHttpBehavior = new WebHttpBehavior();
    
                host.AddServiceEndpoint(typeof(IPolicyRetriever), webHttpBinding, "").Behaviors.Add(webHttpBehavior);
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpsGetEnabled = true;
                host.Description.Behaviors.Add(smb);
                host.Open();
                Console.WriteLine("Host opened");
            }
    

    此外,我对 GetSilverlightPolicy() 函数进行了以下修改:

                         public Stream GetSilverlightPolicy()
            {
                string result =
                    @"<?xml version=""1.0"" encoding=""utf-8""?>
                        <access-policy>
                            <cross-domain-access>
                                <policy>
                                    <allow-from http-request-headers=""SOAPAction"">
                                        <domain uri=""https://""/>
                                        <domain uri=""http://""/>
                                    </allow-from>
                                    <grant-to>
                                        <resource path=""/"" include-subpaths=""true""/>
                                    </grant-to>
                                </policy>
                            </cross-domain-access>
                        </access-policy>";
                return StringToStream(result);
            }
    

    【讨论】:

      【解决方案2】:

      默认情况下,Silverlight 客户端无法向加载 .XAP 文件的域以外的域发出网络请求(即跨域请求)。如果您想访问自托管的 WCF 服务(这意味着 X 域请求),该服务必须向 Silverlight 运行时提供一个策略文件,说明可以发出此类请求。

      您可以在http://blogs.msdn.com/b/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspx 的帖子中找到如何为自托管服务启用跨域调用的示例。由于您的服务使用 HTTPS,因此您也需要使用 HTTPS 来提供策略,否则帖子中的代码应该适合您。

      【讨论】:

      • 问题,有没有办法在clientconfig文件中使用xml来定义这个??
      • 不,这是 服务器 决定是否可以跨域方式调用它,而不是客户端方式(我假设您在谈论 ServiceReferences .clientconfig 文件)。这需要在服务器端完成。
      • 有没有办法在服务本身的 app.config 文件中做到这一点?这就是我启用 SSL 并设置服务行为和 http 绑定的地方。'
      • 我创建了策略检索器类并将我的服务设置为从它继承。现在我试图在我的服务的 app.config 文件中设置它,以使用带有“”端点的策略检索器。 blogs.msdn.com/b/carlosfigueira/archive/2010/07/25/…
      • 是的,这也可以在配置中完成。请记住,策略端点必须位于域根(地址 = "")中,它必须使用 webHttpBinding,并且它必须引用具有 &lt;webHttp/&gt; 行为的端点行为配置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2013-07-17
      • 1970-01-01
      相关资源
      最近更新 更多