【问题标题】:WCF Silverlight CommunicationExceptionWCF Silverlight 通信异常
【发布时间】:2012-04-29 04:25:10
【问题描述】:

这篇文章会很长,对此我事先表示歉意。

我正在尝试使 Silverlight 应用程序与我从 Visual Studio 运行的服务进行通信,目前它没有托管在 IIS 中。我试图让这个原型的代码和配置尽可能少,只是最低限度。互联网上到处都是关于这个问题的答案,但似乎没有一个适用于我的特殊困境。

我的服务方案有一个SimpleServiceAsyncResult,它实现了IAsyncResult接口,一个服务接口,ISimpleService,该服务的实际实现在SimpleService中。该服务实现如下:

public class SimpleService : ISimpleService
{
    public IAsyncResult BeginSimpleMethod(string msg, AsyncCallback callback, object state)
    {
        return new SimpleServiceAsyncResult<string>(msg);
    }

    public string EndSimpleMethod(IAsyncResult result)
    {
        SimpleServiceAsyncResult<string> res = result as SimpleServiceAsyncResult<string>;
        return res.Result;
    }

    public string SimpleMethod(string msg)
    {
        return msg;
    }


    public Message ProvideCrossDomainFile()
    {
        FileStream fileStream = File.Open(@"CrossDomain.xml", FileMode.Open, FileAccess.Read, FileShare.Read);

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.DtdProcessing = DtdProcessing.Parse;

        XmlReader reader = XmlReader.Create(fileStream, settings);

        Message result =  Message.CreateMessage(MessageVersion.None, "", reader);
        return result;
    }

    public Message ProvidePolicyFile()
    {
        FileStream fileStream = File.Open(@"ClientAccessPolicy.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
        XmlReader reader = XmlReader.Create(fileStream);
        Message result = Message.CreateMessage(MessageVersion.None, "", reader);
        return result;
    }
}

项目中有2个xml文件; ClientAccessPolicy.xml 和 CrossDomain.xml,如下所示:

ClientAccessPolicy.xml

<?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>

CrossDomain.xml

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-access-from domain="*" />
  <allow-http-request-headers-from domain="*" headers="SOAPAction" />
</cross-domain-policy> 

还有一个 App.config,如下所示:

App.config

<behaviors>
  <serviceBehaviors>
    <behavior name="SimpleServiceBehavior">
      <serviceMetadata httpGetEnabled="True"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

现在,我想看看所有这些好处是否真的有效。所以我用一个控制台项目创建了一个解决方案,只有一个 Program.cs 和 App.config。

该程序当然没什么特别的,只是最低限度的:

       var factory = new ChannelFactory<ISimpleService>("SimpleService");
        ISimpleService service = factory.CreateChannel();

        var asResult = service.BeginSimpleMethod("tesmsg", null, null);

        Console.WriteLine("Data: " + service.EndSimpleMethod(asResult);

这一切都很好,我得到了我正在寻找的数据,所以我很高兴。 我想要实现的下一个目标是使用 Silverlight 应用从同一个服务中获取一些数据。

为此,我在我的客户端解决方案中创建了一个 Silverlight 项目,创建了服务引用并进行了 soms 管道。我正在尝试通过在 MainPage.xaml.cs 中添加一些代码来执行 SimpleMethod:

    void SimpleMethodCompletedProxyCallback(object sender, SimpleMethodCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            data = e.Result;
        }
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        SimpleServiceClient proxy = new SimpleServiceClient();

        proxy.SimpleMethodCompleted += new EventHandler<SimpleMethodCompletedEventArgs>(SimpleMethodCompletedProxyCallback);
        try
        {

            proxy.SimpleMethodAsync("teststring");
        }
        catch (CommunicationException cex)
        {
            label1.Content = cex.Message;
        }
    }

完成这个管道后,我以为我可以获取一些数据,但是当它尝试调用 SimpleMethod 时,它不断从生成的 ServiceReference 代码中抛出 CommunicationException:

        public string EndSimpleMethod(System.IAsyncResult result) {
            object[] _args = new object[0];
            string _result = ((string)(base.EndInvoke("SimpleMethod", _args, result)));
            return _result;
        }

我已经为此在网上冲浪了几个小时,最终得到了 CrossDomain.xml 和 ClientAccessPolicy.xml 以及会暴露此问题的方法,但无论我尝试什么,我都会遇到同样的异常。我完全不知道下一步该做什么,希望你能在这方面进一步帮助我。

亲切的问候

【问题讨论】:

  • 另外:如果您有 crossdomainpolicy.xml 文件,则不需要 CrossDomain.xml 文件。 CrossDomain.xml 用于 Flash 兼容性,并且没有相同范围的功能...删除它。
  • 我直接从 Visual Studio 中的解决方案运行它,因此 CrossDomain.xml 和 ClientAccesspolicy.xml 在 /bin/Debug 中。但正如我在帖子中所说,使用一个、另一个或两者都与我面临的问题无关。
  • 可能与从visual studio运行有关...

标签: silverlight wcf communicationexception


【解决方案1】:

在您的服务代码中,SimpleService 类实现了一个接口 (ISimpleService),我假设它用 [ServiceContract] 装饰,并定义了五个操作协定(BeginSimpleMethod、EndSimpleMethod、SimpleMethod、ProvideCrossDomainFile、ProvidePolicyFile)。也许 ProvidePolicyFile 也用 [WebGet(UriTemplate = "/clientaccesspolicy.xml")] 装饰。

现在,由于您只有一个接口,因此您有以下两种情况之一:服务器中的端点是 SOAP 端点(例如,basicHttpBinding-based),或者端点是 REST 端点(例如,@987654329 @/webHttp 行为)。

如果是前者,则返回clientaccesspolicy.xml的操作位置不正确。根据documentation for WebGetAttribute 的备注部分,这是一种被动 行为,只有在端点具有WebHttpBehavior 时才会受到尊重。 Silverlight 将在一个地方 (http://your_service/clientaccesspolicy.xml) 查找该策略文件,并且可以在其他地方访问它(http://your_service/endpoint,带有指示方法的 SOAPAction 标头)。

如果是后者,则默认情况下 Silverlight 无法调用这些端点(请参阅有关从 SL 调用 REST/POXREST/JSON 端点的帖子),因此它也不起作用。

http://blogs.msdn.com/b/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspx 上的帖子是 AFAIK 使 SL 能够在自托管 WCF 服务上调用服务的“规范”方式。您将需要两个端点(可能在两个接口中),一个用于服务本身,一个用于策略文件。这篇文章有更多关于这个问题的细节。

【讨论】:

    猜你喜欢
    • 2011-06-27
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多