web-dev-qa-db-ja.com

ASP.NET Web API:(405)メソッドは許可されていません

Web APIコントローラーがあります。それは非常に奇妙に振る舞います。 PostManを使用すると、Web APIでPOSTメソッドにアクセスできますが、.netからHttpWebRequestを使用すると、(405)メソッドが許可されていません。ここにWeb APIコードを配置します。

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

namespace MyProject.Controllers
{
    public class TestController : ApiController
    {
        [HttpPost]
        public int buy(OrderResult value)
        {
            try
            {
                if (value.InvoiceDate != null && value.Result == 1)
                {
                    return 0;
                }
            }
            catch{}

            return -1;
        }
    }

    public class OrderResult
    {
        public int Result { get; set; }
        public long InvoiceNumber { get; set; }
        public string InvoiceDate { get; set; }
        public long TimeStamp { get; set; }
    }
}

これが私のWebApiConfig.csです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace MyProject
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {

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

        }
    }
}

これは、他の.NETプロジェクトからPOSTリクエストを送信する方法です。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;

namespace MyProject.Controllers
{
    public static class WebReq
    {
        public static string PostRequest(string Url, string postParameters)
        {
            try
            {
                HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(Url);
                myReq.Method = "POST";
                myReq.Timeout = 30000;
                myReq.Proxy = null;

                byte[] postData = Encoding.UTF8.GetBytes(postParameters);
                myReq.ContentLength = postData.Length;
                myReq.ContentType = "application/x-www-form-urlencoded";
                using (Stream requestWrite = myReq.GetRequestStream())
                {
                    requestWrite.Write(postData, 0, postData.Length);
                    requestWrite.Close();
                    using (HttpWebResponse webResponse = (HttpWebResponse)myReq.GetResponse())
                    {
                        if (webResponse.StatusCode == HttpStatusCode.OK)
                        {
                            using (Stream str = webResponse.GetResponseStream())
                            {
                                using (StreamReader sr = new StreamReader(str))
                                {
                                    return sr.ReadToEnd();
                                }
                            }
                        }
                        return null;
                    }
                }
            }
            catch (Exception e)
            {
                var message = e.Message;
                return null;
            }
        }

    }
}

私はすでにweb.configに次のコードを追加しました:

<modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule" />
</modules>

PostManからPOSTリクエストを正常に送信できるため、奇妙です。PostManはこのコードをAPIに送信します。

POST /api/Test/buy HTTP/1.1
Host: domain.com
Cache-Control: no-cache
Postman-Token: 9220a4e6-e707-5c5f-ea61-55171a5dd95f
Content-Type: application/x-www-form-urlencoded

InvoiceDate=28012016&Result=1

私は問題を解決するための提案をいただければ幸いです。

9
TechTotal

私は解決策を見つけました。

Fiddlerでリクエストを確認しました。POSTリクエストをAPIに送信すると、この新しいパラメーターAspxAutoDetectCookieSupport=1で同じアドレスに自動的にリダイレクトされます

AspxAutoDetectCookieSupport = 1を削除する方法

最後に、web.configのcookieless="AutoDetect"cookieless="UseCookies"に変更し、問題を解決しました。

3
TechTotal

私はこれが古い投稿であることを知っていますが、多分これは他の誰かを助けるかもしれません。同様の問題が発生し、postmanで投稿を実行しているときに405エラー「Get not allowed」が発生しました。結局、httpsの代わりにhttpを使用してURLに送信していました。 httpsに変更すると修正されました。

6
Paul Reedy
     byte[] postData = Encoding.UTF8.GetBytes(postParameters);
            myReq.ContentLength = postData.Length;
            myReq.ContentType = "application/x-www-form-urlencoded";
            using (Stream requestWrite = myReq.GetRequestStream())
            {
                requestWrite.Write(postData, 0, postData.Length);

適切なx-www-form-urlencodedリクエストを送信していない可能性があります。 postParametersとして渡されたものからデータを適切にエンコードしていない可能性があります。 HttpWebRequestを使用したフォームデータの投稿 を参照してください

X-www-form-urlencodedに従って有効なOrderResultオブジェクトを生成していないため、ルートセレクターはBuyアクションを選択しません。このため、POSTは許可されません。

OrderResult value = nullをオプションのパラメーターに変更したため、コントローラーにアクセスする可能性があります。ただし、次のように動作する奇妙なコントローラーがない限り、これは望ましいことではありません。

Buy(OrderResult value = null)
{
    if(value== null)
        value = MyCustomDeserializeFromRequestBody(RequestContext)

    ...
}

最終的には、このクラスを実際に使用すべきではありません。最新の開発には、はるかに優れた構成があります https://stackoverflow.com/a/31147762/37055https://github.com/ hhariri/EasyHttp 頭の上から

2
Chris Marisic

私の場合、プロジェクト内にルートと同じ名前(サンドボックスなど)の物理フォルダーがあり、POSTリクエストはIIS(明らかに)、WebAPIランタイムの代わり。

予想される404エラーではなく、誤解を招く405エラーが発生したため、トラブルシューティングに時間がかかりました。

これに陥るのは簡単ではありませんが、可能です。それが誰かを助けることを願っています。

0
Panos Roditakis