web-dev-qa-db-ja.com

要求されたリソースはhttpメソッド 'OPTIONS'をサポートしていません。

私は自分のangular.jsクライアントからasp.net web api PUTメソッドに次のリクエストを送信しています。

var org = {
                  OrgId: 111,
                  name: 'testing testing'
          };
$http.put("http://localhost:54822/api/data/putorganisation/1/", org).then(function(status) {
         console.log("success PUT");
         return status.data;
});

ただし、次のerrormsg(fiddler)を取得します。

{"message":"The requested resource does not support http method 'OPTIONS'."}

これは私のasp.net web api web.configファイルの一部です:

 <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type,x-xsrf-token,X-Requested-With" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <remove name="WebDAV" />
    </handlers>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
  </system.webServer>

データコントローラーWeb API:

public HttpResponseMessage Options()
{
            var response = new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.OK;
            return response;
}

public HttpResponseMessage PutOrganisation(int id, [FromBody]Organisation org)
{
  var opStatus = _Repository.UpdateOrganisation(org);
  if (opStatus.Status)
  {
     return Request.CreateResponse<Organisation>(HttpStatusCode.Accepted, org);
  }

return Request.CreateErrorResponse(HttpStatusCode.NotModified, opStatus.ExceptionMessage);
}

これは私の質問です。fiddler(機能)でangularclient(機能しない)とまったく同じ要求を行うと、なぜerrormsg(上記を参照)が表示されるのですか?

15
user603007

私はこれが古い質問であることを知っていますが、同じ問題に遭遇し、理解しようとしている他の人を助けることができると思いました。

Web.configのハンドラー構成のうち2つを削除することで解決しました。

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!--<remove name="OPTIONSVerbHandler" />-->
  <remove name="TRACEVerbHandler" />
  <!--<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />-->
</handlers>

それが問題を解決した理由は正確にはわかりませんが、私の実用的な理論は<remove name="OPTIONSVerbHandler" />はデフォルトでOPTIONSリクエストを禁止します。 Angularを介してリクエストを送信する場合、最初にOPTIONSリクエストを送信してからPUTリクエストを送信します。最初のOPTIONSリクエストがAPIの無効なhttpメソッドとして拒否されたため、PUTリクエストに到達しません。

フィドラーでは、PUTリクエストのみを送信することを前提としています(手動でPostman Webアプリを送信して同じ動作を観察しました)。そのため、禁止されているOPTIONSリクエストをスキップして成功します。

34
Nathan Hanna

私も同じ問題に直面しました、いくつかの調査の後、web.configファイルとGlobal.asax.csファイルに以下の変更を加えました

<configuration>

  <system.webServer>
    <directoryBrowse enabled="true" />
    <validation validateIntegratedModeConfiguration="false" />
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, PATCH, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />

      </customHeaders>
    </httpProtocol>
    <handlers>
      <remove name="WebDAV" />
      <remove name="OPTIONSVerbHandler"/>
      <remove name="TRACEVerbHandler" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />

      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="C:\windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="C:\windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
      <remove name="ApplicationInsightsWebTracking" />
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
    </modules>
  </system.webServer>

</configuration>

次のコードを追加しますglobal.ascx.cs

protected void Application_BeginRequest()
{
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
}
8
Gehan Fernando

ええ、古いですが良い人です。私は同じ問題と症状がありましたが、私の解決策は自分で負ったものです。とにかくそれを共有します。起動時にすべてのMapHttpRoute呼び出しで使用されるコントローラーをサービスが構成する方法には、[DisableCors]属性。別のコントローラーを使用するようにローカルマシンのスタートアップを再構成するとすぐに、すべてが機能しました。したがって、ここにリストされている他のすべてを実行した場合は、コントローラーを確認して、私が行ったように、愚かなことをしていないことを確認してください。

Andrewは正解です。おそらくCORSの問題です。必要なのは、次のようになるようにEnableCors属性をコントローラークラスに追加することです。

 [EnableCors(origins: "https://example.com,http://example.org", headers: "*", methods: "*")]
    public class  TestController : ApiController
    {
         // your code 

これを行う別の方法はこれで言及されています スタックオーバーフローポスト

1
Shekhar

これは、ほぼ間違いなくCORSの問題です。私は最初に それについて読んでください これが何であり、なぜそれが重要なのかを確実に理解できるようにします。そして、私はあなたのサーバー構成が正しくないと思います。

残念ながら、.netについてはあまり知りませんが、この 。netのCORSチュートリアル は、何をすべきかを明確に説明しています。

EnableCorsアノテーションがないようです。 [EnableCors("*", "*", "*")]のようなものをコントローラに追加する必要があるようです。 OPTIONSを明示的に処理する必要はありません。もちろん、プロダクションでは、CORSの処理にワイルドカードを使用したくありません。より具体的にする必要がありますが、テストにはこれで十分です。

1

明らかに、特定のケースでは、CORSにより実際のリクエストを送信しても安全かどうかを判断するために、OPTIONSリクエストが「実際の」リクエストの前に送信されます。 http://www.asp.net/web-api/overview/security/enabling-cross-Origin-requests-in-web-api で次のMS記事を参照し、「Preflightリクエスト"。

以下のQ&Aの一部も役立つ場合があります。

0
djikay