2012-12-26 94 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" , "*"); 
    } 
}