web-dev-qa-db-ja.com

クロスドメインサポートをWCFサービスに追加する方法

POST localhost:80でホストされているjavascriptアプリから、別のポートでホストされているWCF REStfulサービスへのリクエストを許可しようとしていますが、どういうわけか機能しません。追加しようとしましたカスタムプロパティをヘッダーに追加し、サービスのJSONDataメソッドにプログラムで追加しましたが、応答で「405メソッドは許可されていません」がまだ表示されます。ここでの適切なアプローチは何ですか?

これは私のインターフェースです:

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

これは、Web.configバージョンよりもうまく機能しました。

Global.asaxを作成する

このメソッドをGlobal.asax.csに追加します。

using System.Web;

namespace StackOverflow
{
    public class Global : System.Web.HttpApplication
    {
        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

30
Akira Yamamoto

これらのノードを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-リソース/

13
Akira Yamamoto

非GETリクエストに対してCORSを有効にするには、Access-Control-Allow-Originヘッダーを設定するだけでは不十分です。これは、preflightリクエストも処理する必要があるため、OPTIONSリクエストは、実際のリクエストが送信される前に、データを変更する可能性のある操作(POST、PUT、DELETEなど)を実行しても安全かどうかをサーバーに尋ねます。

WCFに対するCORSサポートの追加に関するブログ投稿を作成しました。これは最も単純な実装ではありませんが、うまくいけば、投稿のコードをプロジェクトに単にコピー/貼り付けることができます。投稿は http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx にあります。

9
carlosfigueira

次の.NETコード(global.asax)には、*ではなく、Originドメインをエコーバックすることが重要な違いがあります。これにより、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" , "*");
    }
}
0
QA Collective