Междоменный WCF - ошибка конфигурации Silverlight a: ActionNotSupported - PullRequest
1 голос
/ 12 сентября 2011

Я пытался запустить функции WCF из кода SilverLight. WCF работает на сайте www.my-site.com Приложение Silverlight загружается с сайта www.my-site.com как часть

Вот запрос, который был отправлен моим приложением silverlight:

POST http://www.my -site.com / MyService.svc HTTP / 1.1
Принять: /
Реферер: http://www.my -site.com / ClientBin / MySlApp.xap
Accept-Language: ru-RU
Длина контента: 153
Content-Type: text / xml; кодировка = UTF-8
SOAPAction: "http://tempuri.org/IMyService/Add"
Принять кодировку: gzip, deflate
Пользователь-агент: Mozilla / 5.0 (совместимый; MSIE 9.0; Windows NT 6.1; Trident / 5.0)
Ведущий: www.my-site.com
Подключение: Keep-Alive
Прагма: без кэша

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <Add xmlns="http://tempuri.org/">
      <a1>1</a1>
      <a2>1</a2>
    </Add>
  </s:Body>
</s:Envelope>

В результате я получил следующий ответ:

HTTP / 1.1 500 Внутренняя ошибка сервера
Cache-Control: приватный
Длина контента: 710
Content-Type: application / xml; кодировка = UTF-8
Сервер: Microsoft-IIS / 7.5
X-AspNet-версия: 4.0.30319
X-Powered-By: ASP.NET
Дата: вс, 11 сентября 2011 г. 16:34:19 GMT

<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
  <Code>
    <Value>Sender</Value>
    <Subcode>
      <Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">
        a:ActionNotSupported
      </Value>
    </Subcode>
  </Code>
  <Reason>
    <Text xml:lang="en-US">
      The message with Action '' cannot be processed at the receiver,
      due to a ContractFilter mismatch at the EndpointDispatcher.
      This may be because of either a contract mismatch
      (mismatched Actions between sender and receiver)
      or a binding/security mismatch between the sender and the receiver.
      Check that sender and receiver have the same contract and the same binding
      (including security requirements, e.g. Message, Transport, None).
    </Text>
  </Reason>
</Fault>

Код запроса Silverlight:

        BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
        EndpointAddress endpointAddress =
            new EndpointAddress("http://www.my-site.com/MyService.svc");
        IDbService service =
            new ChannelFactory<IDbService>(basicHttpBinding, endpointAddress)
                .CreateChannel();
        AsyncCallback asy = delegate(IAsyncResult result)
                                {
                                    Trace.WriteLine(service.EndAdd(result));
                                };
        service.BeginAdd(1, 1, asy, null);

Интерфейс контракта операции Silverlight:

[ServiceContract]
public interface IMyService
{
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginAdd(long a1, long a2, AsyncCallback callback, object state);

    long EndAdd(IAsyncResult result);
}

Интерфейс контракта операции WCF:

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    long Add(long a1, long a2);
}

WCF Сервисный код:

[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyService: IMyService
{
    public long Add(long a1, long a2)
    {
        return a1 + a2;
    }
}

часть web.config:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MySlApp.Web.ServiceMyServiceAspNetAjaxBehavior">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="MySlApp.Web.MyServiceAspNetAjaxBehavior">
        <enableWebScript />
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
  <services>
    <service name="MySlApp.Web.DbService"
             behaviorConfiguration="MySlApp.Web.ServiceMyServiceAspNetAjaxBehavior">
      <endpoint address=""
          binding="webHttpBinding" contract="MySlApp.Web.IMyService" />
    </service>
  </services>
</system.serviceModel>

clientaccesspolicy.xml:

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="http://www.my-site.com" />
        <domain uri="http://www.vkontakte.ru" />
        <domain uri="http://*.vkontakte.ru" />
        <domain uri="http://www.vk.com" />
        <domain uri="http://*.vk.com" />
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

crossdomain.xml:

<?xml version="1.0" encoding="utf-8" ?>
<cross-domain-policy>
  <allow-access-from domain="www.my-site.com" />
  <allow-access-from domain="www.vkontakte.ru" />
  <allow-access-from domain="*.vkontakte.ru" />
  <allow-access-from domain="www.vk.com" />
  <allow-access-from domain="*.vk.com" />
</cross-domain-policy>

1 Ответ

1 голос
/ 12 сентября 2011

Это не междоменная проблема.Проблема в том, что вы отправляете запрос, соответствующий basicHttpBinding, в то время как конечная точка сервера использует webHttpBinding.Если вы измените web.config на тот, что указан ниже, он должен работать.

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MySlApp.Web.ServiceMyServiceAspNetAjaxBehavior">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
  <services>
    <service name="MySlApp.Web.DbService"
             behaviorConfiguration="MySlApp.Web.ServiceMyServiceAspNetAjaxBehavior">
      <endpoint address=""
          binding="basicHttpBinding" contract="MySlApp.Web.IMyService" />
    </service>
  </services>
</system.serviceModel>

Если вы не можете изменить свой сервис, вам придется сменить клиента.webHttpBinding конечные точки, также известные как конечные точки WCF WebHttp, или (как-то чрезмерно использующие термин «REST») конечные точки WCF REST не могут быть доступны напрямую через SL с использованием модели программирования WCF (клиентский класс, ChannelFactory<T> и т. Д.).Это можно сделать (см. Статью о потреблении сервисов REST / POX через SL и публикацию о использовании сервисов REST / JSON через SL ), но это не слишком просто (большинстволюди используют простые классы, такие как WebClient или HttpWebRequest, чтобы использовать эти услуги.

...