ASP.NET Web API 2 BadRequest content - asp.net-web-api2

I'm not receiving the expected Response Content on the client when the resource returns BadRequest.
[HttpGet]
[Route("Test", Name = "Test")]
public async Task<IHttpActionResult> Test()
{
var result = BadRequest("test");
return result;
}
On client (see hurl.it example below) I simply receive the string Bad Request in the body:
The response on the server seems to be fine:
It was working fine at some point (returning strings or ModelState in content) and recently we noticed this problem. I can't think of any recent change on server that could cause it.
It works neither locally nor when deployed on server.
It can be reproduced in any ApiController in the project.
return Ok("test"); works as expected.
Does anyone know what can cause this behavior?
Thank you!

It is hard to tell what goes wrong.
Things you could check:
Perhaps is your error caused by invalid authentication request
Try with a new project, if that makes difference then you know it's your project and there are no errors caused by your local IIS and server settings (highly unlikely but you never know.
Check your App_Start folder, containing the BundleConfig, RouteConfig, FilterConfig,WebApiConfig`. Perhaps some custom settings did cause to give you bad request error while it might be a not found error.
Check if it's only on Get request or also on others, could be caused by different versions of assemblies.
Check if you only have the problem with 400, or does 401, 500 gives the same problem?
Check your Web.Config file, these might contain <CustomErrors> that might redirect, or throw there own errors.
After some comments, custom erros seemed to be the problem.

Related

PATCH request losing body on IIS but not on localhost

I have a web API, where I'm trying to support a PATCH request with a JSON Patch body to make changes to an object on the server.
I am using ASP Core with .Net 6, hosting using IIS on my web host.
This is the controller method:
public class BaseDataController<TEntity, TDetail, TNew> : ControllerBase
where TEntity : class, IIdentifiable
{
[HttpPatch("{id}")]
public virtual async Task<ActionResult<TDetail>> Patch(Guid id, [FromBody] JsonPatchDocument<TEntity> patch)
{
var item = await MainService.GetAsync(id);
if (item == null)
{
ControllerLogger.ItemNotFound();
return NotFound();
}
patch.ApplyTo(item, ModelState);
ValidationHelper.ValidatePatch(item, ModelState);
if (!ModelState.IsValid)
return BadRequest(ModelState);
await MainService.UpdateAsync(item);
return this.GuardResult(Mapper, item);
}
}
When I try to use this on my local machine, it works just fine. When I deploy to my web server, and make an identical request, I get a validation error and a 400 status code:
{"errors":{"":["A non-empty request body is required."],"patch":["The patch field is required."]}}
If I change HttpPatch to HttpPost and update the web request accordingly, it works fine.
Can anyone suggest what might be going wrong here? I'm assuming the server is baulking at the PATCH verb, but I can't work out how to make it happy. Googling is coming up with a load of WebDAV things, but the error codes don't match and ASP is clearly receiving the request (proven from the logs) when the description of the WebDAV issues suggests it wouldn't.
My working theory is that IIS is seeing the PATCH verb and doing something to the request body that ASP Core doesn't like, but I can't work out why or where to look to turn that sort of thing off.
When I try to use this on my local machine, it works just fine. When I
deploy to my web server, and make an identical request, I get a
validation error and a 400 status code: If I change HttpPatch to HttpPost and update the web request accordingly, it works fine
Well, your scenario is pretty obvious in context of IIS as you may know Http verb PATCH is not enabled as default accepted http verb on IIS Request Restrictions As you can see below:
Solution:
To resolve above incident, you outght to configure Request Restrictions on IIS and need to include ,PATCH so that it will allow http PATCH verb. On top of that, after that, please restart your application pool. You can follow below steps to implement that:
Step: 1
Select your app on IIS and then click on Handler Mappings Just as following
Step: 2
Select (Double click) ExtensionlessUrlHandler-Integrated-4.0
Step: 3
Click on Request Restrictions
Step: 4
Select VERB then include PATCH by comma seperated value as ,PATCH and click OK finally restart your application pool.
Note: For more details you can have a look on our official document here.

Express JS changing line break type to CRLF

I am trying to make a HTTP request from a Flutter App to a Express-JS Server running on an Ubuntu machine. A newer version of Flutter(v1.22.5) throws following error when making the Request:
E/flutter (29477): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Invalid response, unexpected 10 in reason phrase
The code for making the request looks like this:
final response = await http.get(
'http://XX.XX.XXX.XXX/employees', //Hiding IP address for privacy purposes
headers: {
"Content-Type": "application/json",
"Authorization": api_key,
},
);
print(response.statusCode);
I can confirm by using HTTP-Tester Insomnia that the queried URL does indeed return information.
The issue seems to be known and can be viewed here
According to the Github-Thread, the issue is due to wrong line break format in the headers.
How can I tell Express JS to use CRLF?
For anyone stumbling across this question, I fixed it by reconfiguring my API-Server. Closer inspection of this problem lead to the conclusion that neither the App nor the API was bad, due to the fact no API-Request did actually reach my API-Code. I figured it out by simply looking at the logs. In my case, it was NginX not working properly as a reverse-proxy. I followed this tutorial to properly set it put.

Publishing Asp.net website. This 404 error shows up. What am I missing?

Error 404 shows up after Asp.net published on GitHub. How to finish publishing. What am I missing?
I personally never deployed directly to Github before. Usually when i get a 404 error, I start by checking if all my database is linked correctly. Since secret json doesnt get pushed up when deploying, make sure you add any info in secret.json into Github.
Secondly, I comment out if logic in Startup.cs, so error shows on deployed side. This will invoke to developer exception page which you can use to diagnose what the problem is.
// if (env.IsDevelopment()) <— this one
// {
app.UseDeveloperExceptionPage(); <— have this invoked even on deployed site.
// }
Sorry i am on my phone answering but if its unclear let me know!

IIS 7 Serves GET request correctly to browser but throws timeout exception for API request

I am running a very simple Web application (Asp.Net MVC3) on Win 7 IIS.
I have a very simple HTTP GET API which returns hello world.
Calling:
http://localhost/helloworld
Returns:
Hello World!
This works perfectly over a browser.
But when I write an app which tries to pull this URL using a webclient, I get the following error:
{"Unable to read data from the transport connection: The connection was closed."}
My Code is as follows
WebClient web = new WebClient();
var response = web.DownloadString("http://localhost/helloworld");
My IIS Settings are as follows
What should I be looking at? I have been at this for hours and I have run out of options to try! Any help will be really appreciated!
Thanks.
I suspect it's because WebClient does not send some of the HTTP headers:
A WebClient instance does not send optional HTTP headers by default. If your request requires an optional header, you must add the header to the Headers collection. For example, to retain queries in the response, you must add a user-agent header. Also, servers may return 500 (Internal Server Error) if the user agent header is missing. http://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.80).aspx
Try using HttpWebRequest instead. http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx
I finally figured out what the issue was and instead of it being an IIS specific issue - which I was leaning towards, it turned out to be an issue with the code that I wrote.
Adding details here incase someone else runs into a similar problem.
I had the following method in my code which I was using to send the response of the request as a JSON object.
private void sendJsonResult(string result) {
Response.StatusCode = 200;
Response.Headers.Add("Content-Type", "application/json; charset=utf-8");
Response.Flush();
Response.Write(result);
Response.End();
Response.Close(); // <-- This is the problem statement
}
On digging around a bit, I found out that we should not be doing a Response.Close().
A better explanation of this is here.
Once I removed that line, it started working perfectly - both in my consuming app as well as the web browser, etc.
If you will read the link above, you will clearly understand why we should not be using a Response.Close() - so I will not go into that description. Learnt a new thing today.

The remote server returned an error : 400 badrequest in WCF

In our project, we are calling the .svc file directly from asp.net web page and I receive the error "The remoter server returned an error:(400) bad request.
Our project architecture is, we are using .svc file in our web application and the .cs file for the svc in writter in another class library project. From aspx, we are calling the WCF service directly without adding reference or anything. I cannot change the concept, because it is our standard. I'm able to add service reference and call those methods, but I wanted to call the method directly from .svc url.
I'm pissed off for 2 days and could not resolve the error. We are using HttpWebRequest to get the response from the service. Basically, the service will take Data Transfer Object(DTO) as input and returns the same(DTO) as output with only one value.
Check the following code:
HttpStatusCode statusCode = HttpHelper.PostXmlRequestValue(requestXMLInput,
string.Format("http://{0}/{1}/MySample.svc/webhttp/MyMethodName",
Request.ServerVariable["HTTP_HOST"], Request.ApplicationPath);
The same code works in one machine but not in the other. I have checked the configuration and everything is same, but still I receive the same error.
When I use the .svc url in my machine, it works, but gives a message "Method not allowed". When I checked the same url in the working machine, I got the same message.. I believe there is some simple thing I'm missing out. I couldn't find, as I'm new to WCF.
When using HttpWebRequest the "Method not allowed" error is for example that you are sending a Http GET, when the service expects a Http POST.
HttpWebRequest is a REST based configuration, this limits the complexity of the DTO's that you can send.