繁体   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