Reputation: 1005
I published a WEB API application (.Net Core 3.1) on my Ubuntu 18.04 server and its running behind NGINX. My GET methods are working on local machine as well as on remote server. But my POST methods are only working on my local machine but not on remote server though I tried many things. I get 400 (bad request) error from remote server. I could not figure out what is the reason behind it. Here is my code:
public class MyCls
{
public string MyString { get; set; }
public int MyInt { get; set; }
}
[Route("[controller]")]
[ApiController]
public class NewController : ControllerBase
{
[HttpGet("MyGetRoute")]
public string Method1()
{
return "Hello from server.";
}
[HttpPost("MyPostRoute")]
public MyCls Method2(MyCls str)
{
var options = new JsonSerializerOptions
{
// PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
str.MyString = str.MyString + " John";
str.MyInt = str.MyInt + 2;
return str;
}
[HttpPost("MyPostRoute2")]
public string Method3(MyCls str2)
{
return str2.MyString;
}
}
And here is my code in html page:
function postIt() {
axios.post('New/MyPostRoute', {
MyString: 'Fred',
MyInt: 4,
}
).then(function (response) {
document.getElementById("p1").innerHTML = response.data.myString + " " + response.data.myInt;
console.log(response.Text);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
});
}
function postIt2() {
axios.post('New/MyPostRoute2', {
MyString: 'Fred',
}
).then(function (response) {
document.getElementById("p1").innerHTML = response.data;
console.log(response.Text);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
});
}
function getIt() {
axios.get('New/MyGetRoute')
.then(function (response) {
document.getElementById("p1").innerHTML = response.data;
console.log(response.Text);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
});
}
Here is my NGINX configration:
server {
listen 80;
listen [::]:80;
index index.html home.html
server_name dotnet.xxxxxx.com www.dotnet.xxxxxx.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/xxxxxx.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/xxxxxx.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = dotnet.xxxxxx.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
Upvotes: 0
Views: 1683
Reputation: 387795
If a problem appears after putting it on a different enviroment, then you should always try to find out if that environment’s configuration is the source of the problem. In your case, the application was working fine locally, so it is unlikely that it will suddenly break when deployed in production. Instead, it’s more likely that the reverse proxy you put in front of this is the cause of your problem.
You can also verify this by checking your application logs. If the reverse proxy is mishandling requests, then they will probably not end up reaching your ASP.NET Core application, or they will end up being malformed. So you should either see nothing in the logs, or some proper error.
In this case, the problem is likely with the following nginx configuration:
proxy_set_header Connection 'upgrade';
You shouldn’t set the Connection
header permanently to 'upgrade'
. Upgrading the connection is only used when you want to switch the protocol, most commonly when you are using WebSockets. In that case, you would only want to do this on a subpath though, as it will stop normal requests from working properly.
The correct way to set the Connection
header is to use 'keep-alive'
as you have also done:
proxy_set_header Connection keep-alive;
You should only set each header once anyway. If you remove the Connection 'upgrade'
line and only keep the Connection keep-alive
one, then your requests will likely go through properly.
See also this related answer for a similar problem that appeared for POST endpoints after publishing.
Upvotes: 1