簡體   English   中英

為什么 HttpClient.PostAsync 似乎將請求作為 GET 而不是 POST 發送?

[英]Why does HttpClient.PostAsync appear to be sending the request as a GET rather than POST?

我正在嘗試使用沒有帶有PostAsync方法的主體的 HttpClient發送 POST 請求。 但是,在請求中不斷失敗,並出現405 Method Not Allowed 顯然,請求是作為 GET 請求而不是 POST 發送的(如下圖所示)。

代碼示例:

var response = await new HttpClient().PostAsync("https://api.creativecommons.engineering/v1/auth_tokens/token?client_id=adsf&client_secret=asdf&grant_type=client_credentials", null);
Console.WriteLine(response.RequestMessage);

產生:

Method: GET, RequestUri: 'https://api.creativecommons.engineering/v1/auth_tokens/token/?client_id=adsf&client_secret=asdf&grant_type=client_credentials', Version: 1.1

.NET 小提琴中的示例

我也嘗試過使用 Flurl,但導致了相同的結果(我猜它是在后台使用 HttpClient)。

為什么PostAsync將請求作為 GET 而不是 POST 發送?

在此處輸入圖像描述


更新

由於這個問題在沒有提供一點建設性批評的情況下引起了如此多的仇恨,所以 StackOverflow 做得很好,做得很好。

如果您遇到類似的問題,請注意以下兩點:

  1. 如果響應為 301 (Redirect) ,HttpClient 將自動重定向 它不會將 301 作為狀態碼返回給您!
  2. 當它進行重定向時,它將請求從 POST 更改為 GET 這在技術上是正確的,但是,我不知道它會發生。

這兩件事結合起來,看起來好像請求是作為 GET 發送的,而實際上,它是一個 POST 請求,帶有 301 響應,並自動重定向為 GET。 在某些情況下可能很明顯,有點不幸的是,在我的情況下,差異是 URL 中的一個斜線。

我將 null 發布到該機構,看起來它正在拋出 405 並返回一些信息以查看。 我相信“GET”的顯示是騙人的。

編輯:好的,所以要修改:

首先,post 執行並從服務器接收 301。

Fiddler 顯示帶有 301 響應的 POST

隨后重定向到另一個端點(作為 GET),結果為 405。因此,您的請求的最終結果表現為帶有 405 的 GET。我的錯誤。

在此處輸入圖像描述

在使用集成測試時,由於 https 在默認啟動包含此redirect時,您將遇到此問題

var opt = new RewriteOptions().AddRedirectToHttps();
app.UseRewriter(opt);
app.UseHttpsRedirection();

僅使用 Microsoft 的CustomWebApplicationFactory建議是不夠的。 您必須在 *Fixture 中配置自己的 TestServer,示例如下

            const string baseUrl = "https://localhost:5001";
            const string environmentName = "Test";
            var contentRoot = Environment.CurrentDirectory;

            Configuration = new ConfigurationBuilder()
                .SetBasePath(contentRoot)
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{environmentName}.json", true)
                .AddEnvironmentVariables()
                .Build();
            
            var builder = new WebHostBuilder()
                .UseUrls(baseUrl)
                .UseContentRoot(contentRoot)
                .UseEnvironment(environmentName)
                .UseConfiguration(Configuration)
                .UseStartup<TestStartup>();

            Server = new TestServer(builder) {BaseAddress = new Uri(baseUrl)};

此外,如果您遵循 DDD 並將您的控制器放在不同的項目中,請確保您的 API 項目包含程序集參考

services.AddControllers(options =>
                    options.Filters.Add(new HttpResponseExceptionFilter()))
                .AddApplicationPart(typeof(Startup).Assembly)
                .AddApplicationPart(typeof(MyController).Assembly);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM