这篇文章会很长,我为此提前道歉。
我正在尝试使 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,如下所示:
客户端访问策略.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>
跨域.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,它看起来像:
应用程序配置
<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 以及会暴露此问题的方法,但无论我尝试什么,我都会遇到同样的异常。我完全不知道下一步该做什么,希望你能在这方面进一步帮助我。
亲切的问候