Silverlight - WCF получает доступ к политике на локальном хосте
У меня есть приложение Silverlight, которое использует WCF для связи с сервером. И Silverlight, и WCF работают на локальном компьютере (localhost). Когда Silverlight выполняет вызов службы, происходит сбой с исключением связи. Я понимаю, что это потому, что у меня нет файла cliententaccesspolicy, но поскольку конечная точка WCF работает на http://localhost:port, я определил интерфейс IPolicyRetriver и добавил реализацию в службу, которая возвращает клиентскую политику доступа в поток.
У меня вопрос, что мне нужно настроить, чтобы он работал без проблем? Я понимаю, что мне нужно что-то изменить или добавить в мой файл ServiceReference.ClientConfig, но я не понимаю, что именно. Я включил свой ServiceReference.ClientConfig ниже. Пожалуйста, дайте мне знать, что изменить или добавить к нему, и где в Silverlight добавить этот код. Пожалуйста, не вставляйте сюда никакие ссылки, чтобы помочь мне, поскольку я открывал каждую ссылку, которую мог, в течение последних двух дней - но все еще не понимаю.
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMapService" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="../MapService.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IMapService" contract="MapService.IMapService"
name="BasicHttpBinding_IMapService" />
</client>
</system.serviceModel>
ПОМОГИ МНЕ, ПОЖАЛУЙСТА!
2 ответа
Вы не включили реализацию IPolicyRetriever, о которой упоминаете, но вот пример, который вы можете использовать.
Спецификация интерфейса:
[ServiceContract]
public interface IPolicyRetriever
{
[OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
Stream GetSilverlightPolicy();
//[OperationContract, WebGet(UriTemplate = "/crossdomain.xml")]
//Stream GetFlashPolicy();
}
Реализация интерфейса:
// IPolicyRetriever implementation
private Stream StringToStream(string result)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
return new MemoryStream(Encoding.UTF8.GetBytes(result));
}
public Stream GetSilverlightPolicy()
{
string result = @"<?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>";
return StringToStream(result);
}
Затем вы можете включить следующее в XML-файл конфигурации вашего сервера. Это должно быть на стороне сервера, а не на стороне клиента. Я подчеркиваю это, потому что вы включили конфигурацию клиента выше в свой вопрос.
<behaviors>
<endpointBehaviors>
<behavior name="WebHttpNewBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
...
</behaviors>
<services>
<service behaviorConfiguration="NewBehavior">
<endpoint behaviorConfiguration="WebHttpNewBehavior" binding="webHttpBinding"
bindingConfiguration="" name="PolicyEndpoint" contract="WCFService.IPolicyRetriever" />
...
</service>
</services>
В качестве альтернативы, если вы решите создать свой хост программно (так я делаю, а не использовать файл ClientConfig, поэтому приведенный выше пример может быть не на 100% правильным):
ServiceHost host = new ServiceHost(serviceType);
host.AddServiceEndpoint(typeof(IPolicyRetriever), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
Я знаю, что вы просили не предоставлять ссылки, но я использовал http://blogs.msdn.com/b/asiatech/archive/2010/05/07/how-to-consume-a-self-hosted-wcf-service-in-a-cross-domain-environment-by-silverlight-client.aspx в качестве ссылки для обновления моей памяти, потому что у меня нет доступа к моему проекту Silverlight/WCF прямо сейчас.
Вам не нужно ничего менять в конфигурации службы или коде. Поместите clientaccesspolicy.xml в корень веб-сайта сервиса. Если вы используете Visual Studio, вам может потребоваться изменить свойство, чтобы оно заработало. Silverlight будет искать наличие файла. Я мог бы помочь вам использовать такой инструмент, как Fiddler, чтобы увидеть, где Silverlight ищет файл.
Есть одна ссылка, которая мне показалась очень полезной, но так как вы не хотите никаких ссылок, я не буду ее предоставлять.