这篇文章会很长,我对此表示歉意。
我正在尝试让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;
}
}项目中有两个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。
The program is of course nothing special, just the bare minimum: 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,以及可以暴露这一点的方法,但无论我如何尝试,我都会遇到同样的异常。我完全不知道下一步该做什么,希望你能在这方面进一步帮助我。
亲切的问候
发布于 2011-08-13 00:00:54
在您的服务代码中,SimpleService类实现了一个接口(ISimpleService),我假设它用[ServiceContract]装饰,并定义了五个操作契约(BeginSimpleMethod、EndSimpleMethod、SimpleMethod、ProvideCrossDomainFile、ProvidePolicyFile)。也许ProvidePolicyFile也是用WebGet(UriTemplate = "/clientaccesspolicy.xml")装饰的。
现在,由于您只有一个接口,因此有两种情况:服务器中的端点是SOAP端点(例如,basicHttpBinding-based),或者端点是REST端点(即webHttpBinding/webHttp行为)。
如果是前者,则返回clientaccesspolicy.xml的操作位置不正确。根据documentation for WebGetAttribute上的备注部分,这是一种被动行为,只有在端点具有WebHttpBehavior时才会受到影响。Silverlight将在一个地方(http://your_service/clientaccesspolicy.xml)查找该策略文件,并在其他地方(http://your_service/endpoint,带有指示方法的SOAPAction头)访问它。
如果是后者,那么Silverlight在默认情况下不能调用这些端点(参见从SL调用REST/POX和REST/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服务上的服务。您将需要两个端点(可能在两个接口中),一个用于服务本身,另一个用于策略文件。这篇文章有关于这个问题的更多细节。
https://stackoverflow.com/questions/7040148
复制相似问题