web-dev-qa-db-ja.com

WCFエラー:405 Method Not Allowed

この問題に夢中です。私は2つのプロジェクトでソリューションを持っています。1つはjquery ajax呼び出しを備えたプレーンなhtmlで、もう1つはWCFサービスです。 htmlページは、WCFサービスにajax呼び出しを発行してjson文字列を取得し、表示目的で使用します。

今、問題はデバッグモードで実行するたびに、HTMLページとWCFの両方が異なるポートで開始されます。そして、これは私がテストを行うときに私にとってクロスオリジンの問題を作成しました(つまり、Firefoxで呼び出しタイプ= OPTIONSで405 Method Not Allowedエラーを取得します) ajaxスクリプトの呼び出しメソッドをトリプルチェックしますが、WCFサービスは同じです(GET)。

私はグーグルを検索しましたが、拡張機能をインストールするか、IISでいくつかの構成を実行する必要があることがわかりました。 1つの例に従って、web.configに次の構成を追加しましたが、機能しませんでした。

    <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="crossDomain" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MobileService.webHttpBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="MyServiceBehavior">
          <serviceMetadata httpGetEnabled="true"  />
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <services>
      <service name="MobileService.SimpleMemberInfo" behaviorConfiguration="MyServiceBehavior">
        <endpoint address="" binding="webHttpBinding" contract="MobileService.IMemberInfo" bindingConfiguration="crossDomain" behaviorConfiguration="MobileService.webHttpBehavior">
        </endpoint>
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET" />
        <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
      </customHeaders>
    </httpProtocol>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
    </system.webServer>

この迷惑な問題を取り除くためのアイデアはありますか?

編集:追加するだけで、IIS VS Studio 2012に付属するExpressでデバッグを実行しています

WCFコードの追加とweb.configの更新

[ServiceContract]
public interface IMemberInfo
{
    [WebInvoke(Method = "GET",
           BodyStyle = WebMessageBodyStyle.Wrapped,
           ResponseFormat = WebMessageFormat.Json
    )]
    [OperationContract]
    string GetMemberInfoById();
    // TODO: Add your service operations here
}

私のスクリプト:

$(document).ready(function () {
    $.ajax("http://localhost:32972/SimpleMemberInfo.svc/GetMemberInfoById", {
        cache: false,
        beforeSend: function (xhr) {
            $.mobile.showPageLoadingMsg();
        },
        complete: function () {
            $.mobile.hidePageLoadingMsg();
        },
        contentType: 'application/json',
        dataType: 'json',
        type: 'GET',
        error: function () {
            alert('Something awful happened');
        },
        success: function (data) {
            var s = "";

            s += "<li>" + data + "</li>";
            $("#myList").html(s);

        }
    });
});
17
ipohfly

クロスドメインコールにJSONPを使用してブラウザーの制限を回避し、crossDomainScriptAccessEnabledをtrueに設定してweb.configを更新し、サーバーの制限を取得する必要があります。ここの答えには良い例があります: wcfサービスを消費するためにjquery ajaxでクロスドメインポリシーを回避する方法?

GETリクエストに問題がある場合もあります。ここに概説されている修正を試してください: GET要求でWCF Webサービスを機能させる

全体で、次のようなweb.configが必要です。

<bindings>
  <webHttpBinding>
    <binding name="crossDomain" crossDomainScriptAccessEnabled="true" />
  </webHttpBinding>
</bindings>
<behaviors>
  <endpointBehavior>
    <behavior name="restBehavior">
      <webHttp />
    </behavior>
  </endpointBehavior>
  <serviceBehavior>         
     <behavior name="MyServiceBehavior">
        <serviceMetadata httpGetEnabled="true"  />
        <serviceDebug includeExceptionDetailInFaults="true"/>
     </behavior>
  </serviceBehavior>
</behaviors>
<services>
  <service name="..." behaviorConfiguration="MyServiceBehavior">
    <endpoint address="" binding="webHttpBinding" bindingConfiguration="crossDomain" 
              contract="..." behaviorConfigurations="restBehavior" /> 
  </service>
</services>

(サービスとエンドポイントの両方にビヘイビアが関連付けられており、それぞれwebHttp呼び出しとhttpGet呼び出しが許可されていることに注意してください。また、バインディングではcrossDomainアクセスが明示的に有効になっています)。

...このように装飾されたサービスメソッド:

[ServiceContract]
public interface IMyService
{
    [WebGet] // Required Attribute to allow GET
    [OperationContract]
    string MyMethod(string MyParam);
}

...およびJSONPを使用したクライアント呼び出し:

<script type="text/javascript">
$(document).ready(function() {
    var url =  "...";
    $.getJSON(url + "?callback=?", null, function(result) { // Note crucial ?callback=?
       // Process result
    });
});
</script>
10
Jude Fisher

しかし、それは古いスレッドですが、私が直面した問題とCORSの作業のために得た解決策についてコメントを追加したいと思います。次の環境でWebサービスを開発しています。

  1. WCF Webサービス。
  2. .NET 3.5フレームワーク。
  3. 既存のasp.net Webサイトにwcf Webサービスを追加しました。
  4. Visual Studio 2008

ほとんどの人は、web.configの<webHttpBinding>の下のタグにcrossDomainScriptAccessEnabled属性を追加することについて言及しました。これが機能するかどうかはわかりませんが、3.5バージョンでは使用できないため、選択の余地はありませんでした。また、web.configに次のタグを追加すると動作することもわかりました...

<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET" /> <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> </customHeaders> </httpProtocol>

しかし運はありません...

これらのオプションに苦労した後、以下に示すように、これらのヘッダーをglobal.asaxファイルに動的に追加する別のソリューションを見つけました...

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("Cache-Control", "no-cache");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
}

そしてweb.configから削除します。 Webサイトを公開し、クライアント側のjquery/ajaxに進みます... API呼び出しからデータを取得します。幸運を!

8
RamKr

一番下にCORSのリワークに関するいくつかの問題を追加したい-それに関する問題は、入力がGETおよびPOSTメソッドをサポートしていない場合、OPTIONSリクエストが実際に正しいを返さないことです許可されたヘッダー。WCFエンドポイントで実際に許可されているメソッドを実際に調べているわけではありません。クライアントがOPTIONSリクエストを実行するときに、アプリケーション内のすべてのエンドポイントで「GET、POST」サポート対象を尋ねるクライアント)。

OPTIONSメソッドの情報に実際に依存してメソッドの有効なリストを返さない場合(これはCORSリクエストの場合のように)-これはおそらく大丈夫です-もしそうなら、あなたは次のようなことをする必要がありますこの質問の解決策: Ajax JQUERYの処理方法POST WCF self-Hostでのリクエスト

基本的に、各エンドポイントは以下を実装する必要があります。

Webinvoke(Method="OPTIONS", UriTemplate="")

そして、適切なヘッダーを応答にロードする適切なメソッド(そのエンドポイントの適切な「Access-Control-Allow-Method」リストを含む)を呼び出し元に呼び出します。ホストされているWCFエンドポイントがこれを自動的に行わないのはちょっと残念ですが、これはエンドポイントをより細かく制御できる回避策です。そのソリューションでは、適切な応答ヘッダーがエンドポイント実装でロードされます。

public void GetOptions()
    {
        // The data loaded in these headers should match whatever it is you support on the endpoint
        // for your application. 
        // For Origin: The "*" should really be a list of valid cross site domains for better security
        // For Methods: The list should be the list of support methods for the endpoint
        // For Allowed Headers: The list should be the supported header for your application

        WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
        WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
    }
2
jeremyh