2012-12-26 45 views
15

我试图允许来自托管在localhost:80的JavaScript应用程序的POST请求到托管在不同端口的WCF REStful服务,但不知何故它不起作用。我已经尝试向头添加自定义属性,并在我的服务的JSONData方法中以编程方式添加它,但我仍然在我的回复中收到'405方法不允许'。这里有什么合适的方法?如何将跨域支持添加到WCF服务

这是我的接口:

namespace RestService 
{ 
    public class RestServiceImpl : IRestServiceImpl 
    { 
     #region IRestServiceImpl Members 

     public string JSONData() 
     { 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
      return "Your POST request"; 
     } 

     #endregion 
    } 
} 

和服务代码:

using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.Web.Script.Services; 

namespace RestService 
{ 

    [ServiceContract] 
    public interface IRestServiceImpl 
    { 
     [OperationContract] 
     [ScriptMethod] 
     [WebInvoke(Method = "POST", 
      ResponseFormat = WebMessageFormat.Json, 
      BodyStyle = WebMessageBodyStyle.Bare, 
      UriTemplate = "export")] 
     string JSONData(); 
    } 
} 

最后的配置:

<?xml version="1.0"?> 
<configuration> 

    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <services> 
     <service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour"> 
     <endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web"> 
     </endpoint> 
     </service> 
    </services> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior name="ServiceBehaviour"> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="web"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*" /> 
     </customHeaders> 
</httpProtocol> 
    </system.webServer> 

</configuration> 
+0

这将是一个非常好的问题,如果你描述什么“,但不知何故不工作”的意思。 –

+0

我已更新说明。 –

回答

17

这对我来说比在Web.config版本更好地工作:

创建Global.asax

将此代码添加到t他Global.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin" , "*"); 
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
    { 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
     HttpContext.Current.Response.End(); 
    } 
} 

http://www.dotnet-tricks.com/Tutorial/wcf/X8QN260412-Calling-Cross-Domain-WCF-Service-using-Jquery.html

+0

很酷,谢谢你仍然在这里交配! –

+0

非常感谢!终于找到了确切的解决方案,搜索了很多。 – Vikrant

+0

伟大的这个经过几个小时的研究终于奏效了。谢谢bru! –

7

非GET启用CORS请求需要超过只需设置Access-Control-Allow-Origin标题 - 它也需要处理预检请求,它们是OPTIONS请求,要求服务器在发送实际请求之前执行可能会更改数据的操作是安全的(例如POST,PUT,DELETE)。

我写了一篇关于为WCF添加CORS支持的博客文章。这不是最简单的实现,但希望帖子中的代码可以简单地复制/粘贴到您的项目中。该帖子可在http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx找到。

+0

这几乎是我需要的。但我已经注意到,如果您将数据作为json发送,它将不起作用。您的exabple页面会通过POST请求发送一个字符串值。或者,也许这是因为ExtJS处理请求数据的方式不同于jQuery:/ –

+0

该示例确实将数据作为JSON发送 - POST/PUT方法的输入是* JSON字符串*(注意输入被包装在'''s中) 。它也适用于对象,只是在这个例子中,操作将一个字符串作为参数。 – carlosfigueira

+0

我将测试页中的数据更改为'var data = {0} {0} {0} {{我得到了400个错误的请求,我检查了日志,但没有任何帮助,所以我应该在WCF中进行更改以支持它吗? –

4

UPDATE:

这些节点添加到Web.config:

<configuration> 
    <system.webServer> 
    <httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*"/> 
     <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> 
     <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" /> 
     <add name="Access-Control-Max-Age" value="1728000" /> 
     </customHeaders> 
    </httpProtocol> 
    </system.webServer> 
</configuration> 

http://theagilecoder.wordpress.com/2014/07/07/wcf-and-cors-no-access-control-allow-origin-header-is-present-on-the-requested-resource/

+0

适合我! – FranP

0

下面的.NET代码(Global.asax中)有一个重要的区别是,在*代替,它可以更好地回显原产地领域,因为这使对身份验证CORS(例如NTLM/Kerberos)以及预检。

void Application_BeginRequest(object sender, EventArgs e) 
{ 
    if (Request.HttpMethod == "OPTIONS") 
    { 
     Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
     Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
     Response.AddHeader("Access-Control-Max-Age", "1728000"); 
     Response.End(); 
    } 
    else 
    { 
     Response.AddHeader("Access-Control-Allow-Credentials", "true"); 

     if (Request.Headers["Origin"] != null) 
      Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]); 
     else 
      Response.AddHeader("Access-Control-Allow-Origin" , "*"); 
    } 
}