web-dev-qa-db-ja.com

Web API-405-要求されたリソースはhttpメソッド「PUT」をサポートしていません

Web APIプロジェクトがあり、そのプロジェクトに対して「PUT/Patch」リクエストを有効にできません。

フィドラーからの応答は次のとおりです。


HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Allow: GET,POST,DELETE
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcZG90TmV0XFdlYkFQSVxBZFNlcnZpY2VcQWRTZXJ2aWNlXGFwaVxpbXByZXNzaW9uXDE1?=
X-Powered-By: ASP.NET
Date: Tue, 06 May 2014 14:10:35 GMT
Content-Length: 72

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

上記の応答に基づいて、「PUT」動詞は受け入れられません。ただし、関連するハンドラーが構成されている場所を把握することはできません。

クラスの「Put」メソッドは次のように宣言されます。

[HttpPatch]
[HttpPut]
public HttpResponseMessage Put(Int32 aID, [FromBody] ImpressionModel impressionModel)
{
     bla, bla, bla, bla
}

次のスレッドで説明されている変更を読んで実装しました。- Asp.NET Web API-405-このページへのアクセスに使用されるHTTP動詞は許可されていません-ハンドラーマッピングの設定方法 - http://www.asp.net/web-api/overview/testing-and-debugging/troubleshooting-http-405-errors-after-publishing-web-api-applications

Web APIプロジェクトに対して「PUT」コマンドを発行しようとすると405の応答が得られるため、何も機能しません。

ApplicationsHost.configファイルのすべての「ハンドラー」もコメントアウトしました。

VS2012 PremiumおよびIIS Express(バージョン8と想定しています)。VSDev Serverも試しましたが、同じ結果が得られました。

私はアイデアがありません。任意の助けをいただければ幸いです。

リーに感謝

19
LeeVDuhl

属性ルーティングを使用していますか?

この神秘的なエラーは、ルート属性の問題でした。これは、WebAPIConfigで次のように有効になります。

 config.MapHttpAttributeRoutes(); 

Web Api Controllersは、「動詞ベースのアクションメソッドと従来のアクション名ルーティングの混合をホストできない」ことが判明しました。 https://aspnetwebstack.codeplex.com/workitem/184

一言で言えば:API Controllerのすべてのアクションを[Route]属性でマークする必要がありました。従来のルーティング

APIコントローラー:

[RoutePrefix("api/quotes")]
public class QuotesController : ApiController
{
    ...

    // POST api/Quote
    [ResponseType(typeof(Quote))]
    [Route]
    public IHttpActionResult PostQuote(Quote quote)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Quotes.Add(quote);
        db.SaveChanges();

        return CreatedAtRoute("", new { id = quote.QuoteId }, quote);
    }

注:ルートには名前が付けられていないため、CreatedAtRoute()名は空の文字列になります。

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

    }
}

お役に立てれば

22
proggrock

私はあなたとまったく同じ問題を抱えていて、あなたが試したすべてのことを試しましたが、解決策が非常に簡単で鼻の下にあることがあります。あなたはそれを期待しないで、より複雑な理由を探し続けます。 Webメソッドをテストするために呼び出すURLで、パラメーター名がコントローラーメソッド宣言の名前と一致していることを確認してください。私の405問題は、これを行うだけで解決しました(クエリパラメーターを使用していました)。

私のクライアントコントローラー:

...

[HttpPut]
public string PutClient(string username = "", string phone= ""){...}

私のWebApiConfigで:

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
     name: "DefaultApi",
     routeTemplate: "api/{controller}"
);

そして、メソッドのテストに使用するパスは次のようにする必要があります(正しいWebメソッドを適用するには、Postmanなどを使用します)

http://localhost:49216/api/clients?username=Kurt&phone=443332211

それ以外の場合、そのコントローラーでそのhttpメソッドに対して405を取得します。 web.configを変更する必要はまったくありませんでした(webdavなどを削除する必要はありません)。ドキュメントのソースについて this を確認します。

たとえば、次のアクションを検討してください。

public void Get(int id)

IdパラメーターはURIにバインドします。したがって、このアクションは、ルートディクショナリまたはクエリ文字列のいずれかに、「id」の値を含むURIとのみ一致できます。

オプションのパラメーターはオプションであるため、例外です。オプションのパラメーターの場合、バインディングがURIから値を取得できない場合でも問題ありません。

10
kurt

これは、PUTメソッドの最初のパラメーター名を変更したときに起こりました

public void Put(int code, [FromBody]Lead lead)

そのはず:

public void Put(int id, [FromBody]Lead lead)

そして、これはそれが呼ばれる方法です:

$.ajax({
    type: "PUT",
    data: json,
    url: "../api/leadsapi/123",
    contentType: "application/json; charset=utf-8"
});
4
Daniel Cardenas

この答えは私のために問題を修正しました。 Route属性を追加する必要があり、問題は解決しました。

    [HttpPut]
    [Route("")]
    public HttpResponseMessage MyMethod()
1
Dave Shinkle

同じ問題を抱えていたので、これを解決するには3つのことをする必要がありました:

  1. <modules>および<handlers>でWebdavを無効にします
  2. WebAPIを使用する場合、HttpPutがSystem.Web.Httpからのものであり、System.Web.Mvcからのものではないことを確認してください
  3. このようにExtensionlessUrlHandlerを有効にします

<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="%windir%\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="%windir%\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" />

これがあなたの一部がこの厄介な問題を解決するのに役立つことを願っています...

1
Ben Croughs

これは、APIコントローラーのPut()メソッドをパブリックにすることを忘れた場合に返されるエラーメッセージでもあります。これは後知恵では明らかですが、10分間のひっかき傷を負わせました。

1
Dylan Beattie

Web.configのHandlerセクションの下に次のセクションを追加します。

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

例えば:

<handlers>
    <remove name="WebDAV" />
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
0
Sulabh Singla

私にとっては、他の多くのポスターが主張したとおりでした。 webapiconfigですべてが正しく設定されている可能性がありますが、愚かなものが欠落しているだけです。

私の場合、次のように定義されたルートがありました。

[HttpPut]
    [Route("api/MilestonePut/{Milestone_ID}")]
    public void Put(int id, [FromBody]Milestone milestone)
    {
        db.Entry(milestone).State = System.Data.Entity.EntityState.Modified;
        db.SaveChanges();
    }

問題が発生しましたか?このパラメーターは、ルートではMilestone_IDとして定義されますが、関数自体ではidとして定義されます。 .NETはこれを実現するのに十分スマートだと思うでしょうが、それは間違いなく機能せず、機能しません。

次のようにパラメーターに一致するように変更したら:

[HttpPut]
    [Route("api/MilestonePut/{id}")]
    public void Put(int id, [FromBody]Milestone milestone)
    {
        db.Entry(milestone).State = System.Data.Entity.EntityState.Modified;
        db.SaveChanges();
    }

すべてが魅力のように機能しました。

0
Indy-Jones

たぶん今は遅いですが、誰かがこれを使うことができます。

PUTリクエストを使用したかったため、文字列化されたオブジェクトをWeb APIに送信し、putメソッドでそのオブジェクトのみを受け入れました。

[〜#〜] jquery [〜#〜]

let musterija = {
            Name: name,
            Email: email,
            Password: password,
            Username: logUser.Username,
            Lastname: lastname,
            GenderString: gender,
            Jmbg: identification,
            PhoneNumber: phone,
        };

        $.ajax({
            method: "PUT",
            url: "/api/Musterija",
            data: JSON.stringify(musterija),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function () {
                alert("Entity updated");
                EmptyAllInputs();
                $('#divprofile').show();
                $('#divupdate').hide();
            },
            error: function (msg) {
                alert("Fail - " + msg.responseText);
            }
        });

WEB API

    [HttpPut]
    public HttpResponseMessage PutMusterija(Musterija m)
0
Serlok

Webサーバーの設定で設定する必要があります。それはあなたがそれを行うことができるウェブサーバーのタイプに依存します。たとえば、IISでは、web.configファイルを使用して、ドキュメントルートでそれを行うことができます。クロスオリジンリクエストでは、レスポンスにCORSヘッダーを追加して、オリジン、メソッドなどを許可する必要があります...

注:おそらく、ASP.NETフレームワークでもこれについて何かを行うことができますが、そうではないと思います。

0
inf3rno