跨域 WCF - Silverlight 配置错误 a:ActionNotSupported

发布于 2024-12-04 09:02:28 字数 5676 浏览 1 评论 0原文

我尝试从 SilverLight 代码运行 WCF 函数。 WCF 正在网站 www.my-site.com 上运行 Silverlight 应用程序可从网站 www.my-site.com 下载,如下所示: IFrame>>从网站 www.vkontakte.ru 下载的 html 页面的一部分。我收到 a:ActionNotSupported 错误。
怎么了?

以下是我的 silverlight 应用程序发送的请求:

POST http://www.my-site.com /MyService.svc HTTP/1.1
接受:/
引用者:http://www.my-site.com/ClientBin/MySlApp.xap
接受语言:ru-RU
内容长度:153
内容类型: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
连接:保持活动
Pragma: no-cache

<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 Internal Server Error
缓存控制:私有
内容长度:710
内容类型:application/xml;字符集=utf-8
服务器:Microsoft-IIS/7.5
X-AspNet-版本:4.0.30319
X-Powered-By:ASP.NET
日期:2011 年 9 月 11 日星期日 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>

I tried to run WCF functions from SilverLight Code. WCF is runing on site www.my-site.com
Silverlight application is downloaded from site www.my-site.com as < IFrame/> part of html page which is downloaded from site www.vkontakte.ru. I have received an a:ActionNotSupported error.
What is wrong?

Here is request that was sent by my silverlight application:

POST http://www.my-site.com/MyService.svc HTTP/1.1
Accept: /
Referer: http://www.my-site.com/ClientBin/MySlApp.xap
Accept-Language: ru-RU
Content-Length: 153
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://tempuri.org/IMyService/Add"
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Host: www.my-site.com
Connection: Keep-Alive
Pragma: no-cache

<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>

As result I have recieved folowing response:

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Length: 710
Content-Type: application/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sun, 11 Sep 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 request code:

        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 operation contract interface:

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

    long EndAdd(IAsyncResult result);
}

WCF operation contract interface:

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

WCF Service code:

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

part of 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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长梦不多时 2024-12-11 09:02:28

这不是跨域问题。问题在于您发送的请求符合 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 端点,无法使用 WCF 编程模型(客户端类,ChannelFactory 等)。这是可以完成的(请参阅有关通过 SL 使用 REST/POX 服务,以及关于 消费 REST/通过 SL 的 JSON 服务),但这并不是一件太容易的事情(大多数人使用简单的类,例如 WebClientHttpWebRequest 来使用这些服务。

That is not a cross-domain problem. The issue is that you're sending a request which conforms to the basicHttpBinding, while the server endpoint uses the webHttpBinding. If you change the web.config to the one listed below, it should work.

<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>

If you can't change your service, then you'll need to change the client. webHttpBinding endpoints also known as WCF WebHttp endpoints, or (somehow overusing the 'REST' term) WCF REST endpoints, can't be accessed directly via SL using the WCF programming model (client class, ChannelFactory<T>, etc). It can be done (see the post about consuming REST/POX services via SL, and the post about consuming REST/JSON services via SL), but it's not something too easy (most people use simple classes such as WebClient or HttpWebRequest to consume those services.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文