2012-12-26 38 views
15

Tôi đang cố gắng cho phép yêu cầu POST từ ứng dụng javascript của tôi được lưu trữ tại máy chủ cục bộ: 80 vào dịch vụ WCF REStful được lưu trữ tại một cổng khác, nhưng bằng cách nào đó nó không hoạt động. Tôi đã thử thêm thuộc tính tùy chỉnh vào tiêu đề, cũng như thêm thuộc tính tùy chỉnh theo phương thức JSONData của dịch vụ của tôi nhưng tôi vẫn nhận được '405 Phương thức không được phép' trong phản hồi của tôi. Cách tiếp cận thích hợp ở đây là gì?Cách thêm hỗ trợ miền chéo vào dịch vụ WCF

Đây là giao diện của tôi:

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

và mã dịch vụ:

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(); 
    } 
} 

Và cuối cùng là cấu hình:

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

Sẽ là một câu hỏi hay nếu bạn mô tả những gì "nhưng bằng cách nào đó nó không hoạt động" có nghĩa là. –

+0

Tôi đã cập nhật mô tả. –

Trả lời

17

này làm việc tốt hơn cho tôi hơn so với phiên bản Web.config:

Tạo một Global.asax

Thêm mã này vào t ông 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

Tuyệt vời, cảm ơn vì vẫn còn ở đây! –

+0

Cảm ơn rất nhiều! cuối cùng đã có giải pháp chính xác, sau khi tìm kiếm rất nhiều. – Vikrant

+0

Điều này cuối cùng đã làm việc sau một vài giờ nghiên cứu. Cảm ơn bru! –

7

Kích hoạt CORS cho phi GET yêu cầu đòi hỏi nhiều hơn chỉ cần đặt tiêu đề Access-Control-Allow-Origin - nó cũng cần phải xử lý yêu cầu preflight là OPTIONS yêu cầu máy chủ có an toàn thực hiện các hoạt động có khả năng thay đổi dữ liệu (ví dụ: POST, PUT, DELETE) trước khi yêu cầu thực tế được gửi hay không.

Tôi đã viết một bài đăng blog về việc thêm hỗ trợ CORS cho WCF. Nó không phải là cách triển khai đơn giản nhất, nhưng hy vọng mã trong bài đăng có thể được sao chép/dán vào dự án của bạn một cách đơn giản. Bài đăng có thể được tìm thấy tại http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx.

+0

Đó là gần như những gì tôi cần. Nhưng tôi đã nhận thấy rằng nó không hoạt động nếu bạn gửi dữ liệu dưới dạng json. Trang exabple của bạn sẽ gửi một giá trị chuỗi duy nhất với yêu cầu POST. Hoặc có thể bởi vì ExtJS xử lý dữ liệu yêu cầu khác với jQuery:/ –

+0

Ví dụ gửi dữ liệu dưới dạng JSON - đầu vào cho các phương thức POST/PUT là * JSON strings * (chú ý rằng đầu vào được bao bọc trong '' ') Nó cũng làm việc cho các đối tượng, nó chỉ là trong ví dụ, thao tác lấy một chuỗi như một tham số – carlosfigueira

+0

Tôi đã thay đổi dữ liệu trong trang thử nghiệm thành 'var data = { foo:" bar " };' và tôi nhận được 400 yêu cầu Bad.Tôi đã kiểm tra các bản ghi nhưng không có gì hữu ích ở đó.Vì vậy, tôi nên thực hiện thay đổi cũng trong WCF chính nó để hỗ trợ nó? –

4

UPDATE:

Thêm các nút vào 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

Làm việc hoàn hảo cho tôi! – FranP

0

Mã NET sau (global.asax) có một sự khác biệt quan trọng là thay cho *, nó có thể được tốt hơn để echo lại lĩnh vực Xuất xứ vì điều này cho phép xác thực hơn CORS (ví dụ NTLM/Kerberos) cũng như Preflight.

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" , "*"); 
    } 
} 
Các vấn đề liên quan