C# 无法访问silverlight应用程序中的自托管wcf服务

C# 无法访问silverlight应用程序中的自托管wcf服务,c#,wcf,silverlight,service,C#,Wcf,Silverlight,Service,我试图从我的Silverlight应用程序中访问一个自托管WCF服务,但它不起作用。该服务配置为使用SSL,我可以使用WCFTestClient工具(一种web浏览器)点击它,我可以引用该服务并从silverlight项目中更新它。问题是,当silverlight应用程序尝试调用该服务时,会出现以下错误: 服务器没有提供有意义的回复;这可能是由于契约不匹配、会话过早关闭或内部服务器错误造成的 当我使用WCF测试客户端工具点击它时,它返回的数据没有任何问题(如预期的那样) 有什么想法吗 以下是我的

我试图从我的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>

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


您可以在以下位置的帖子中找到如何为自托管服务启用跨域调用的示例。由于您的服务使用HTTPS,因此您也需要使用HTTPS来提供策略,但如果不是这样,帖子中的代码应该适合您。

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


您可以在以下位置的帖子中找到如何为自托管服务启用跨域调用的示例。由于您的服务使用HTTPS,因此您也需要使用HTTPS来服务策略,但如果不是这样,帖子中的代码应该适合您。

@carlos:您的代码非常适合http。但是,我无法让它为https工作。我只是得到“clientaccesspolicy.xml”找不到

我对主要功能进行了以下修改:

                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");
        }
                     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);
        }
此外,我还对GetSilverlightPolicy()函数进行了以下修改:

                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");
        }
                     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);
        }
公共流GetSilverlightPolicy()
{
字符串结果=
@"
";
返回StringToStream(结果);
}

@carlos:您的代码对http非常有效。但是,我无法让它为https工作。我只是得到“clientaccesspolicy.xml”找不到

我对主要功能进行了以下修改:

                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");
        }
                     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);
        }
此外,我还对GetSilverlightPolicy()函数进行了以下修改:

                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");
        }
                     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);
        }
公共流GetSilverlightPolicy()
{
字符串结果=
@"
";
返回StringToStream(结果);
}

Question,有没有一种方法可以使用xml在clientconfig文件中定义它?没有,这是服务器决定是否可以跨域调用它,而不是客户端调用它(我假设您谈论的是ServiceReferences.clientconfig文件)。这需要在服务器端完成。是否有办法在服务本身的app.config文件中完成?这就是我启用SSL并设置服务行为和http绑定的地方。”我创建了策略检索器类,并将我的服务设置为从中继承。现在,我正在尝试在我的服务的app.config文件中设置它,以便将policyretriever与“”端点一起使用。是的,这也可以在配置中完成。请记住,策略终结点必须位于域根目录中(address=“”),它必须使用
webHttpBinding
,并且必须引用具有
行为的终结点行为配置。问题,是否有方法使用xml在clientconfig文件中定义此项?否,这是一个服务器决定是否可以跨域调用它,而不是客户端(我假设您谈论的是servicerences.clientconfig文件)。这需要在服务器端完成。是否有办法在服务本身的app.config文件中完成?这就是我启用SSL并设置服务行为和http绑定的地方。”我创建了策略检索器类,并将我的服务设置为从中继承。现在,我正在尝试在我的服务的app.config文件中设置它,以便将policyretriever与“”端点一起使用。是的,这也可以在配置中完成。请记住,策略终结点必须位于域根目录(address=“”),它必须使用
webHttpBinding
,并且它必须引用具有
行为的终结点行为配置。