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

Posted

技术标签:

【中文标题】跨域 WCF - Silverlight 配置错误 a:ActionNotSupported【英文标题】:Crossdomain WCF - Silverlight configuration error a:ActionNotSupported 【发布时间】:2011-11-15 04:38:36 【问题描述】:

我尝试从 SilverLight 代码运行 WCF 函数。 WCF 在网站 www.my-site.com 上运行 Silverlight 应用程序是从站点 www.my-site.com 下载的,作为从站点 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 内容类型:文本/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 连接:保持活动 编译指示:无缓存

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

【问题讨论】:

您将其创建为与 Silverlight 兼容的 WCF 服务还是普通的旧 WCF 服务? 【参考方案1】:

这不是跨域问题。问题是您发送的请求符合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&lt;T&gt; 等)通过 SL 直接访问。可以做到(参见关于consuming REST/POX services via SL 的帖子和关于consuming REST/JSON services via SL 的帖子),但这并不是一件容易的事(大多数人使用简单的类,例如WebClientHttpWebRequest 来使用这些服务。

【讨论】:

以上是关于跨域 WCF - Silverlight 配置错误 a:ActionNotSupported的主要内容,如果未能解决你的问题,请参考以下文章

WCF 跨域策略安全错误

WCF跨域策略安全性错误

Silverlight 到 WCF 跨域异常,但正在成功读取 clientaccesspolicy.xml

Silverlight WCF 超时

如何针对已部署的服务 [跨域问题] 调试 Silverlight 应用程序?

Silverlight wcf 连接错误