Silverlight访问webService跨域问题的解决之一

调试清单
     检查服务是否正在运行

     检查配置

     检查跨域问题

     检查是否已启用异常

     检查网络上的内容

检查服务是否正在运行
在 Silverlight 客户端上查找问题之前,请确认正在访问的服务正常运行。对此进行检查的一种方法是将服务地址键入 Web 浏览器。此处所需的服务地址是 ServiceReferences.ClientConfig 文件的 <endpoint> 元素中的 address 属性的值。请注意,这不是键入到“添加服务引用”对话框中的地址。“服务帮助页”功能经常可用,输入地址后将显示一个页面,指示服务是否正常运行。如果 “服务帮助页”无法显示,则错误页将指示服务是否正常运行,并且会提供一个可用作调试起点的消息。

通常,测试服务是否运行的更可靠的一种方法是使用测试工具尝试与服务进行对话(如 WCF 测试客户端)。

查明是否是服务代码而不是 Silverlight 客户端代码出现问题的另一种非常可靠但有时开销较大的方法是,尝试从非 Silverlight 客户端使用服务。例如,创建新的控制台应用程序类型项目,像在 Silverlight 项目中一样对该项目执行“添加服务引用”,然后再次将服务使用代码添加到
Main()
内,就像在 Silverlight 应用程序中一样。使用
Console.WriteLine
显示结果。

检查配置
第一步是检查 Silverlight 客户端是否配置正确。您应该有一个名为 ServiceReferences.ClientConfig 的文件,该文件由“添加服务引用”工具生成。检查正在使用 IService 协定访问相关服务的 CustomerService 客户端的文件。生成的配置文件应如以下内容所示。

复制代码
<configuration>
<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding
         name="BasicHttpBinding_IService"
         maxBufferSize="65536"
         maxReceivedMessageSize="65536">
         <security mode="None" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
       <endpoint
        address="http://localhost:61424/WebSite5/Service.svc "
        binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IService"
        contract="CustomerClient.CustomerService.IService"
        name="BasicHttpBinding_Service" />
    </client>
</system.serviceModel>
</configuration>
请注意,您添加对其引用的服务只有一个 <endpoint> 元素,并且在 Silverlight 应用程序正确配置的情况下绑定为 basicHttpBinding 绑定。

如果服务中没有 <endpoint> 元素,则您的服务可能实际上配置不正确,无法被 Silverlight 2.0 应用程序访问。Silverlight 2.0 应用程序只能与使用 SOAP 1.1 的简单 SOAP 服务对话,无法处理任何高级的 WS-* 协议,如 WS-Addressing 或 WS-Security。如果使用 ASP.NET Web 服务,则客户端应仅默认使用此简单配置。有关 ServiceReferences.ClientConfig 文件中的设置,请参阅在 Silverlight 客户端中配置 Web 服务使用。

如果使用的是服务的 WCF 技术,则应该检查客户端上的配置,即使客户端 ServiceReferences.ClientConfig 看似正确。从服务中打开 Web.config 文件并查找 <system.serviceModel> 元素。

复制代码
<system.serviceModel>
...
   <services>
      <service name="MyProject.Service">
         <endpoint
            address=""
            binding="basicHttpBinding"
            contract="MyProject.IService" />
         <endpoint
            address="mex"
            binding="mexHttpBinding"
            contract="IMetadataExchange" />
      </service>
   </services>
</system.serviceModel>
查找其协定属性引用了 Silverlight 2.0 客户端正在访问的服务的 <endpoint> 元素。确保 binding 属性的值已设置为“basicHttpBinding”。其他 <endpoint> 元素可用于具有其他绑定的其他协定。例如在前面的示例中,"mex" 终结点用于为服务提供元数据。 有关 配置服务,请参阅使用配置文件配置服务。

检查跨域问题(承载服务必须和webservice在一个服务器上)
有几个与 Silverlight 应用程序相关的 URL,区分这些 URL 对于构建可能出现的跨域问题的讨论非常重要。启动应用程序时,出现在浏览器中的 URL 称为“应用程序 URL”。此 URL 通常类似如下显示:http://localhost:1111/something/MyGraphicalApp.aspx 。请注意,此处真正重要的是 XAP 文件的 URL,在此例中可能显示为 http://localhost:1111/somethingelse/MyGraphicalApp.xap ,但在大多数较简单的情况下,此 URL 与承载的网页将处于相同的域中,因此可以忽略此区别。然后,查看 ServiceReferences.ClientConfig 文件中的“服务 URL”:例如 http://localhost:5678/somepath/TestService.svc 和 local.live.com/SearchService/LocalSearch.asmx。

导致跨域问题的一个常见错误是从 file:// 应用程序 URL 运行 Silverlight 应用程序。在 Visual Studio 2008 中使用 F5 功能运行 Silverlight 应用程序时,也可能会遇到此问题。若要避免此问题,请右键单击项目中的 .aspx 页并选择“在浏览器中查看”。

若要了解跨域问题,请务必了解 URL 的哪个部分指定域。域基本上是介于 http:// 和 URL 中接下来出现的第一个斜杠 / 之间的部分。其中包括端口号(如果未明确指定,则假设使用 80)等。如果应用程序 URL 的域不同于服务 URL 的域,则表明为跨域情形。甚至端口号或域名的一个部分不同 ,都会导致此类问题的出现。例如,您的应用程序位于 http://localhost:1111/something/MyGraphicalApp.aspx ,它尝试调入 http://localhost:5678/somepath/TestService.svc ,则出现跨域情形,因为 localhost:1111 是与 localhost:5678 不同的域。

跨域访问服务要求服务具有跨域策略文件。有以下两种跨域策略文件:Clientaccesspolicy.xml 和 Crossdomain.xml(放在根目录)。 如果希望服务跨域运行,则必须存在其中之一。有关更多信息,请参见 使服务跨域边界可用。

有一种简便的方法可检查是否已为跨域访问正确设置服务。打开浏览器并浏览至 http://service_domain/clientaccesspolicy.xml ,然后浏览至 http://service_domain/crossdomain.xml 。如果存在其中之一,有效且已配置为允许跨域访问,则可以跨域访问服务。

一个常见错误是将跨域策略文件放在不是域根目录的某个位置:例如将 Clientaccesspolicy.xml 文件放在 http://localhost:5678/somepath/clientaccesspolicy.xml 而不是 http://localhost:5678/clientaccesspolicy.xml 。处理较旧的(比如 .NET Framework 2.0)项目时,很容易遇到这种情形。

同时,请确保检查这些文件的语法。分析其中一个文件时出现错误将视为该文件不存在。请注意,Clientaccesspolicy.xml 和 Crossdomain.xml 文件使用不同的语法。确保为选择使用的文件类型使用适当的内容。

检查是否已启用异常
通常,Silverlight 生成的异常消息中不会提供太多的信息。详细的异常信息需要大量的空间,尤其是在需要将其转换为 Silverlight 支持的所有语言时。因此,不包括详细信息是为了使 Silverlight 下载尽可能小而在设计时作出的决定。有关如何修改 Silverlight 2.0 清单文件以启用完整异常的说明,请参阅 Silverlight 2.0 发行说明。

而且,如果访问 WCF 服务,通常不会返回服务器上所引发异常的太多信息。这是一种安全措施:通常不希望将有关服务的内部信息暴露给外界(如何查看WCF异常详情查看本博客WebService异常封装 http://hi.baidu.com/evaandlean/blog/item/3b913012663286d8f7039ef9.html )。

在任何情况下(通常是在 Web 服务方案中),有用的异常信息都包含于若干外部层异常包装的 innerException 中。因此在获得一个异常时,不要仅查看异常本身。还要查看嵌套的
innerException
的所有层次结构,以提取有关问题来源的尽可能多的信息。


检查网络上的内容
调试 Silverlight 服务使用问题的最根本的方法是使用“HTTP 侦察”工具,如 http://www.fiddlertool.com/fiddler/http://projects.nikhilk.net/webdevhelper/ 。这些工具将显示发生的实际 HTTP 流量。在使用该工具之前,请确保先在服务器上启用异常,如上节所述。

同时启动 Silverlight 应用程序和工具,然后让应用程序调用 Web 服务。下面是您可能会看到的一些常见模式:

1. 无:您的 HTTP 侦察工具可能配置不正确。尝试运行另一个非 Silverlight 应用程序(如一般 Web 浏览器),以确保该工具运行正常。或者,您的应用程序可能已损坏。在调用服务的位置放一个断点,以确保实际调用了服务。您可能还存在配置问题,在这种情况 下应参考前面的配置一节。您可能会尝试从 file:// 或 https:// URL 承载应用程序,或者尝试调用 https:// 服务。

2. 仅服务请求:如果您的网络上看到对服务的实际请求,则您已经避免了跨域情形。确定该地址是否为预期的地址。查看网络上返回的内容。内容是否已超时,或者遇 到 404 错误?您的服务或甚至 WCF 本身可能设置不正确。是否返回了 SOAP 错误?如果是,请仔细阅读错误中的内容,通常其中包含了用于调试该问题的足够信息。一般情况下,请仔细查看请求和回复,包括正文和 HTTP 标头。是否已删除任何内容以便让代理通过编译?服务实际上可能要求使用删除的某些项。例如,它可能要求使用某些 SOAP 标头。

3. 先请求 Clientaccesspolicy.xml(之后可能是 Crossdomain.xml),然后请求服务:您存在跨域情形,但是已成功设置跨域策略文件。现在,这种情形和模式 2 基本相同。

4. 仅请求 Clientaccesspolicy.xml,无其他:很大程度上这是因为 Clientaccesspolicy.xml 格式不正确,或者它包含禁止跨域访问的策略。

5. 请求 Clientaccesspolicy.xml,然后请求 Crossdomain.xml,无其他:基本上,很可能是跨域策略文件出现问题。是否收到 404 错误?请检查是否以正确的方式承载文件以及是否在正确的位置。是否实际收到了文件?请检查是其格式不正确,还是禁止了跨域访问。

如何编写Clientaccesspolicy.xml 和 Crossdomain.xml详见本博客

Silverlight访问webService跨域问题的解决之二

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值