Reputation: 6341
I've been trying to send a POST request using HttpClient without a body using the PostAsync
method. However, to my utter bewildement, the request is getting sent as a GET
and not a POST
.
Naturally, the request fails with a 405 Method Not Allowed
becase the server doesn't allow GET
.
Code sample:
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);
Produces:
Method: GET, RequestUri: 'https://api.creativecommons.engineering/v1/auth_tokens/token/?client_id=adsf&client_secret=asdf&grant_type=client_credentials', Version: 1.1
I've also tried using Flurl, but lead to the same result (I am guessing it is using HttpClient under the hood).
Any ideas why PostAsync
is sending the request as a GET rather than POST?
This question got quite a bit of hate without offering an ounce of constructive criticism... Well done StackOverflow, really well done, so much for being more welcoming...
If you come across a similar issue, here are the three things to look for:
RequestMessage
. This may be obvious in some cases, but in my case, the redirect involved adding a single /
not something easily visible in the debugger window!https://api.creativecommons.engineering/v1/auth_tokens/token?client_id=adsf&client_secret=asdf&grant_type=client_credentials
https://api.creativecommons.engineering/v1/auth_tokens/token/?client_id=adsf&client_secret=asdf&grant_type=client_credentials
^
Upvotes: 3
Views: 2002
Reputation: 534
When utilizing integration testing you will run into this issue due to https redirect
when the default startup contains this
var opt = new RewriteOptions().AddRedirectToHttps();
app.UseRewriter(opt);
app.UseHttpsRedirection();
It's not enough to use the CustomWebApplicationFactory
suggestion from Microsoft. You'll have to configure your own TestServer in your *Fixture, example below
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)};
Additionally if you follow DDD and have your Controllers in a different project, make sure your API project contains Assembly reference
services.AddControllers(options =>
options.Filters.Add(new HttpResponseExceptionFilter()))
.AddApplicationPart(typeof(Startup).Assembly)
.AddApplicationPart(typeof(MyController).Assembly);
Upvotes: 0
Reputation: 1196
I posted null to that body, looks like it is throwing a 405 and returning some information to look into. I believe the display of "GET" is deceiving.
EDIT: Ok, so to revise:
First the post executes and receives a 301 from the server.
Followed by a redirect to another endpoint (as a GET) with the result of 405. Thus, the net result of your request manifested as a GET with a 405. My mistake.
Upvotes: 1