I am trying to send a large string to c# controller. controller signature looks like this:
public async Task<IHttpActionResult> Post([FromBody] string longString)
I am getting longString as null. I am doing the same in Postman and see that if turn off the default Content-Length header which says: "calculated when request is sent" and add the same header with a value that equal the length of the string + 8 the back end gets correct value as it does when default Content-Length header is on. My POST request from Angular has everything the same except the value of Content-Length header. It is equal the length of the string + 6. So, I am trying to change Content-Length header value to the one that works in Postman like this:
headers = new HttpHeaders().set('Content-Type', 'application/json;');
headers.set('Content-Length', '140317');
But Network shows that the above change is not taking a place.
Any idea how get it work?
Thanks
Related
I have the following JSON
{"name":"tester1","type":"frontend"}
{"name":"tester2","type":"midlleware"}
{"name":"tester3","type":"backend"}
When I paste the above into Postman with an application/JSON, only the 1st row/JSON will be passed to the function because of the lack of commas between each row. Note, I cannot change the incoming JSON format nor the Content-Type (application/JSON). Also note this is a valid multipart JSON
See here
My API method is as follows:
public async Task<HttpResponseMessage> ProcessJson([FromBody] string _incomingJSON)
Note: I can change my signature ([FromBody] string _incomingJSON)
_incomingJSON is null if I use application/JSON but populated if I use text/plain (which I can't use)
Is there any way I can handle this format with application/JSON and not get _incomingJSON as null?
Thanks in advance
You should send with Postman in 3 rows like this:
Given the following method in a controller for a ASP.NET Web API:
[HttpGet]
[ApiRoute("resource/{id}/end-point)]
public IHttpActionResult MethodName (int id, string clientTimeZone)
{
...
}
Whenever I submit a GET request to http://localhost:5684/api/v1/resource/1/end-point?client_timezone=%2B0500 clientTimezone is passed in to clientTimeZone as %2B0500 and it parses the encoded '+' sign into a space character. Why can't ASP.NET decode +'s from the URI?
In the header I have "ContentType = application/json" and a bearer token
I am trying to get "+0500" into my method but it is turning into " 0500"
Are you using Content-Type of application/x-www-form-urlencoded when consuming the api? This will treat a '+' character as a space when used in your URL.
More details here:
When to encode space to plus (+) or %20?
Try changing your Content-Type to application/json instead and see if parameter binding behaves as expected.
I am using postman to test my .net core API, when i am trying to post data via postman form-data this returns a 415 even if i set the Content-Type header to application/json as the common solution for this issue appears to be online.
If i fire the request without any files via the raw postman option and set the content type as JSON(application/json) this request reaches the API successfully.
Here is how my API looks:
[HttpPost("{organization}")]
public IActionResult Post([FromBody] Asset asset, string organization)
{
//Api body
//Get files from request
Task uploadBlob = BlobFunctions.UploadBlobAsync(_blobContainer,Request.Form.Files[0]);
}
And here is how the failed postman request looks like
and the header for that request
What else am i missing for this to work?
Small update
This works fine if i remove [FromBody]Asset asset and just pass the file
Try using the [FromForm] attribute instead of the [FromBody] attribute:
[HttpPost("{organization}")]
public IActionResult Post([FromForm] string asset, string organization, IFormFile fileToPost)
{
//Api body
Asset asset = JsonConvert.DeserializeObject<Asset>(asset);
//Get files from request
Task uploadBlob = BlobFunctions.UploadBlobAsync(_blobContainer, fileToPost);
}
I can't say for sure, but my guess is that in postman, since you're making a form-data request, your content-type would end up being "multipart/form-data" (if you debug the request when it is being processed, you can see that the content type changes to multipart even though you set it to application/json).
But in your Controller's POST action you specify that you expect an Asset object from the body (which expects a JSON object by default). So you get a 415 since your request's content type is multipart while your API expects application/json because you used the [FromBody] attribute.
Turns out that for some weird reason I was not allowed to pass any of them as a variable of my controller but it works if I retrieve both from the Request.
if (!Request.Form.ContainsKey("asset"))
{
return BadRequest("Asset cannot be empty");
}
Asset asset = JsonConvert.DeserializeObject<Asset>(Request.Form.First(a => a.Key == "asset").Value);
and for the file
var file = equest.Form.Files[0]
Not sure why this is the case and would appreciate if someone could explain this to me but this seems to solve my issue.
I send a file via POST to my ApiController.
If the file is below 2 MB, everything works like a charm.
If the file is bigger, I get a Error 404.
This is the (old) function declaration in my Controller:
[HttpPost]
public HttpResponseMessage FileUpload(HttpRequestMessage req, string entryId = "", string owner = "", int debug = 0)
{
which returns, if the entity is too large, this:
Remote Address:172.17.41.12:443
Request URL:https://webdevserver/myapp/api/Debug/FileUpload
Request Method:POST
Status Code:404 Not Found
or if it is inside the size limits, this:
Remote Address:172.17.41.12:443
Request URL:https://webdevserver/myapp/api/Debug/FileUpload
Request Method:POST
Status Code:200 OK
So I want to send a useful error message - which Error 404 definitely is NOT! - and stumbled upon HTTP Status Code 413, which IIS doesn't send automatically :( so I changed my code to:
[HttpPost]
public HttpResponseMessage FileUpload(HttpRequestMessage req=null, string entryId = "", string owner = "", int debug = 0)
{
if(req==null) {
// POST was not handed over to my function by IIS
// now is it possible to check whether file was empty or too large!? Because
return new HttpResponseMessage(HttpStatusCode.RequestEntityTooLarge);
// should only be sent if POST content was really too large!
So, how can I check whether the size of the POST data was too big or POST was empty?
According to this blog, the status code 404.13 was introduced in IIS 7 to replace the http status code 413.
Since this was done by design, I would suggest that you maintain the response as is, and in your code try to determine whether the 404 error was actually a 404.13 error.
I have an ASP.NET MVC web site. One of my routes is a URL that takes 5 parameters. For the sake of illustration, these parameters are named parameter1, parameter2, parameter3, parameter4, and parameter5. Currently, I'm constructing a URL in some C# code that will POST to the mvc action via a WebClient. that code looks like this:
WebClient myWebClient = new WebClient();
myWebClient.UploadStringCompleted += myWebClient_UploadStringCompleted;
string url = "http://www.example.com/customer/" + parameter1 + "/orders/" + parameter2 + "/" + parameter3 + "/" + parameter4 + "/" + parameter5;
myWebClient.UploadStringAsync(new Uri(url, UriKind.Absolute));
I'm confident that the UploadString method does a POST. I need to do a POST, because my parameter values can be very long. In fact, I estimate that occasionally, the total url length may be 20000 characters long. Regardless, I get a 400 error when I attempt to post my data. In an effort to debug this, I'm trying to figure out how to simulate a POST in Fiddler.
Assuming that I am passing values via a query string as shown above, what values do I enter into Fiddler? From the Composer tab, I'm not sure what to enter for the Request Headers area. I'm also not entirely sure what to enter for the url. I'm not sure if I put the entire URL in there, including the parameter values, or if those belong in the Request Headers.
What I need to enter into Fiddler, so that I can debug my issue?
Basically all your parameters are a part of the URL, and this is the root of your problem. Here is what is going on: you are hitting the URL length limitation, and receiving a "400 Bad request" error. In real world most web browsers do not work with URLs more than 2000 characters long.
To resolve this problem I would suggest doing a bit of refactoring, so that request is posted to the URL http://www.example.com/customer/parameter1/orders or even http://www.example.com/customer/orders with parameters send in request body. Here is how test such request in Fiddler:
On Composer tab choose POST request verb
Specify the URL as
http://www.example.com/customer/parameter1/orders
or
http://www.example.com/customer/orders
In Request Headers section you can set content type header like
Content-Type: application/x-www-form-urlencoded
or any other header you might require. Or just leave it blank which will work in your case.
Finally in Request Body field list your parameters in query string form
parameter1name=parameter1value¶meter2name=parameter2value
In this new case here is how you can send such a request using WebClient:
WebClient myWebClient = new WebClient();
myWebClient.UploadStringCompleted += myWebClient_UploadStringCompleted;
string url = "http://www.example.com/customer/orders";
string data = "parameter1name=parameter1value¶meter2name=parameter2value";
myWebClient.UploadStringAsync(new Uri(url, UriKind.Absolute), data);
I simply mimic the exact request that was sent.
This is how I do it:
Open Fiddler
Go to the page that I want to re-issue the command i.e. repeat the bug step but watch for the request in the list
Select it from the list and right-click, go to replay > reissue and edit
This build a replicated request but hits a break point before it is sent (You will see the red bar on the right)
Above this you can edit the values that were sent by double-clicking on any of them in Headers, QueryString etc
Then hit Run to Complete