Междоменный WCF — ошибка конфигурации Silverlight a: ActionNotSupported
-
29-10-2019 - |
Вопрос
Я попытался запустить функции WCF из кода SilverLight.WCF находится на сайте www.my-site.com Silverlight Application загружается с сайта www.my-site.com как <iframe/> Часть HTML-страницы, которая загружается с сайта www.vkontakte.ru.Я получил а: ActionNotSupported ошибка.
Что не так?
Вот запрос, отправленный моим приложением Silverlight:
ПОЧТА http://www.my-site.com/MyService.svc HTTP/1.1
Принимать: /
Реферер: http://www.my-site.com/ClientBin/MySlApp.xap
Принять-Язык:ру-RU
Длина контента:153
Тип содержимого:текст/xml;кодировка = utf-8
SOAPДействие:"http://tempuri.org/IMyService/Add"
Принять-кодирование:gzip, сдуть
Пользователь-Агент:Mozilla/5.0 (совместим;МСИЕ 9.0;Windows НТ 6.1;Трезубец/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 Внутренняя ошибка сервера
Управление кэшем:частный
Длина контента:710
Тип содержимого:приложение/xml;кодировка = utf-8
Сервер:Microsoft-IIS/7.5
Версия X-AspNet:4.0.30319
X-Powered-By:АСП.НЕТ
Дата:Вс, 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>
кроссдомен.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>
Решение
Это не междоменная проблема.Проблема в том, что вы отправляете запрос, который соответствует 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
потреблять эти услуги.