Доступ к собственной службе WCF из Silverlight 4 - PullRequest
1 голос
/ 18 февраля 2011

У меня есть собственная служба WCF 4, которая обслуживает тот же контракт через basicHttpBinding для клиентов Silverlight 4 и wsHttpBinding для остальных. Код очень короткий и простой и приведен здесь.

Я получаю следующую ошибку при попытке доступа к методу службы из WCF:

Сообщение = Произошла ошибка при попытке сделать запрос к URI http://localhost:8008/WCF4Silverlight.MyService/SL. Это могло быть из-за попытки доступа к услуге междоменным способом без надлежащая междоменная политика или политика, которая не подходит для сервисов SOAP. Вам может понадобиться связаться с владельцем сервиса, чтобы опубликовать файл междоменной политики и убедиться, что он позволяет Связанные с SOAP HTTP-заголовки для отправки. Эта ошибка также может быть вызвана использование внутренних типов в прокси веб-службы без использования Атрибут InternalsVisibleToAttribute. Пожалуйста, смотрите внутреннее исключение для более подробной информации.

У меня есть метод GetClientAccessPolicy (), который обслуживает междоменную политику с помощью атрибута WebGet, и я уверен, что есть проблема с ее правильным раскрытием. Ваше понимание проблемы будет высоко оценено. Если я наберу http://localhost:8008/WCF4Silverlight.MyService/clientaccesspolicy.xml в браузере, я получу xml для того же самого, но вызов Silverlight всегда завершается неудачей с указанной выше ошибкой.

Вот код службы WCF:

 namespace WCF4Silverlight
{
    [ServiceContract(SessionMode = SessionMode.NotAllowed)]
    public interface IClientAccessPolicy 
    { 
        [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]    
        Stream GetClientAccessPolicy();
    }
}
namespace WCF4Silverlight
{
public class MyService: IMyService, IClientAccessPolicy
{
public Stream GetClientAccessPolicy() 
{ 
const 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>"; 
if (WebOperationContext.Current != null)                
WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml"; return new MemoryStream(Encoding.UTF8.GetBytes(result)); 
}
}
//Other service methods....
}

Вот код, который публикует сервис:

class Program
{
 static void Main(string[] args)
 {
  ServiceHost myServiceHost = new ServiceHost(typeof(MyService));
  myServiceHost.Open();

  //Wait for client action.

  myServiceHost.Close();
 }
}

Вот файл app.config для хоста службы WCF:

<service name="WCF4Silverlight.MyService" behaviorConfiguration="MyServiceBehavior">
 <host>
   <baseAddresses>
  <add baseAddress="http://localhost:8008/MyService/"/>
   </baseAddresses>
 </host>
 <endpoint address="general" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMyService" contract="WCF4Silverlight.IMyService"/>
 <endpoint address="SL" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding_IMyService" contract="WCF4Silverlight.IMyService"/>
 <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBinding_IMyService" behaviorConfiguration="webHttpBehavior" contract="WCF4Silverlight.IClientAccessPolicy" />
</service>

А вот ServiceReferences.ClientConfig для клиента Silverlight:

<system.serviceModel>
 <bindings>
  <basicHttpBinding>
   <binding name="BasicHttpBinding_IMyService" maxBufferSize="2147483647"
    maxReceivedMessageSize="2147483647">
    <security mode="None" />
   </binding>
  </basicHttpBinding>
  <customBinding>
   <binding name="WSHttpBinding_IMyService">
    <textMessageEncoding messageVersion="Default" writeEncoding="utf-8" />
    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
   </binding>
  </customBinding>
 </bindings>
 <client>
  <endpoint address="http://localhost:8008/MyService/SL"
   binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
   contract="myWCFService.IMyService" name="BasicHttpBinding_IMyService" />
 </client>
</system.serviceModel>

Ответы [ 4 ]

2 голосов
/ 30 сентября 2011

Самостоятельные службы на машинах без IIS, где клиентская политика доступа не может обслуживаться из корня, вместо этого можно использовать этот метод для динамического обслуживания политики на порту 80:

http://blogs.msdn.com/b/carlosfigueira/archive/2010/07/25/enabling-cross-domain-calls-for-sl-apps-on-self-hosted-tcp-services.aspx

2 голосов
/ 22 февраля 2011

Вот что я сделал, чтобы решить проблему:

1) Использовал Fiddler, чтобы увидеть, куда были направлены вызовы WCF. Фиддлер сказал, что вызовы не были приняты HOST - http: / localhost: 8008 и URL - /clientaccesspolicy.xml.

2) Создан другой класс ClientAccessPolicy, реализующий IClientAccessPolicy (с WebGet для /clientaccesspolicy.xml).

3) Добавлен еще один раздел в app.config хоста для нового сервиса, в котором размещен класс Clientaccesspolicy. У этого был базовый адрес http: / localhost: 8008 /

    <service name="WCF4Silverlight.ClientAccessPolicy" behaviorConfiguration="ClientAccessPolicyBehavior"> 
 <host> 
   <baseAddresses> 
  <add baseAddress="http://localhost:8008/"/> 
   </baseAddresses> 
 </host> 
 <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBinding_IMyService" behaviorConfiguration="webHttpBehavior" contract="WCF4Silverlight.IClientAccessPolicy" /> 
</service>

4) В коде хостинга создал еще один экземпляр ServiceHost и запустил новый сервис с Clientaccesspolicy

ServiceHost clientAccessPolicyHost = new ServiceHost(typeof(ClientAccessPolicy)); clientAccessPolicyHost.Open(); 

5) В клиенте Silverlight удалил существующую ссылку на WCF и добавил ее во вновь размещенную службу.

Теперь происходят вызовы WCF от Silverlight.

1 голос
/ 19 февраля 2011

Самый простой способ отладить проблемы такого рода - использовать Fiddler (www.fiddler2.com) для перехвата HTTP-трафика.Вы сразу увидите, запрашивается ли clientAccessPolicy.xml, где он ожидается и каков результат.

Если вы получите 404 (ресурс не найден), файл не находится в ожидаемом месте (но ваша аннотация webGet выглядит хорошо для меня), иначе проблема заключается в самом xml.

Это очень допустимый clientAccessPolicy.xml, который я обычно использую для целей разработки / тестирования:

<?xml version="1.0" ?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
0 голосов
/ 19 февраля 2011

Если вы используете автономный веб-сервис, вам нужно выбросить файл ClientAccessPolicy.xml в корень веб-сайта, доступ к которому можно получить через порт 80 вашего компьютера (например, http://localhost:80/ClientAccessPolicy.xml).новинка в Silverlight 4, и, к сожалению, я не нашел, что это ясно объяснено в документах MS (упомянуто, но не очень понятно).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...