I'm trying to get write Controller (in asp.net core) code to handle my fineuploader requests but it keeps failing to see the request data despite whatever combination of [FromForm] / [FromBody] / "Content-Type": 'application/json' I use. Here is my uploader config in the view page:
var uploader = new qq.FineUploader({
element: document.getElementById("uploader"),
request: {
endpoint: '#Url.Action("AddAttachment", "Util")',
customHeaders: {
"RequestVerificationToken": '#GetAntiXsrfRequestToken()',
"Content-Type": 'application/json'
}
},
And here is my controller code - not alot for now, I just literally want to see some data getting sent.
public JsonResult AddAttachment([FromForm] Object o){
//var x = HttpContext.Request;
//return Json(x);
if(o == null){
return Json("no data");
}else{
return Json(o);
}
}
and her is what I see fineuploader sending to the server via the network tab in the chrome devtools:
------WebKitFormBoundarySQwYoYovQOkoFU1f
Content-Disposition: form-data; name="test"
876
------WebKitFormBoundarySQwYoYovQOkoFU1f
Content-Disposition: form-data; name="qquuid"
9ba04b80-b3d8-4e2d-8068-792dd77253bd
------WebKitFormBoundarySQwYoYovQOkoFU1f
Content-Disposition: form-data; name="qqfilename"
dohPlayDat.PNG
------WebKitFormBoundarySQwYoYovQOkoFU1f
Content-Disposition: form-data; name="qqtotalfilesize"
3535659
------WebKitFormBoundarySQwYoYovQOkoFU1f
Content-Disposition: form-data; name="qqfile"; filename="dohPlayDat.PNG"
Content-Type: image/png
------WebKitFormBoundarySQwYoYovQOkoFU1f-
Can anyone see the mistake I'm making?
If everything's wired up correctly, you should be able to see your file via Request.Form.Files in the controller.
I was trying to get it as a byte array by action's parameters but had no luck. Try this instead.
The following snippet is an example of how you can bind all the fields from the file upload request, then use the file stream to write the file to a temporary file.
public async Task<IActionResult> Post(string qquuid, string qqfilename, int qqtotalfilesize, IFormFile qqfile)
{
// full path to file in temp location
var filePath = Path.GetTempFileName();
if (qqfile.Length > 0)
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await qqfile.CopyToAsync(stream);
}
}
}
For more information about using .NET Core to upload files you can have a look over here : https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.1
Related
This code:
using (var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(10) })
{
using (var content = new MultipartFormDataContent())
{
content.Add(new StringContent("abc"), "token");
var response = await client.PostAsync("http://localhost", content);
var result = await response.Content.ReadAsStringAsync();
}
}
Generates the following HTTP request:
POST http://localhost/ HTTP/1.1
Host: localhost
Content-Type: multipart/form-data; boundary="4b39ed14-752b-480a-9846-fc0019132d15"
Content-Length: 174
--4b39ed14-752b-480a-9846-fc0019132d15
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=token
abc
--4b39ed14-752b-480a-9846-fc0019132d15--
We have a client who says their WAF is blocking the request because the name parameter should be quoted
Content-Disposition: form-data; name="token"
I have seen some differences in opinion on this:
https://github.com/akka/akka/issues/18788
https://github.com/akka/akka-http/issues/386
Does anyone know what is correct here?
I posted this to https://github.com/dotnet/runtime/issues/72447
Either form is correct, apparently
ASP.NET Core MVC 2
I need to send big raw data (the byte[]). My POST-request contains the Content-Type: application/octet-stream header.
This is the controller action:
[HttpPost]
public async Task<IActionResult> RawBinaryDataManual()
{
using (var ms = new MemoryStream())
{
await Request.Body.CopyToAsync(ms);
var bytes = ms.ToArray();
return StatusCode((int) HttpStatusCode.OK);
}
}
It works fine when I post 22Mb file, but I get the Exception thrown: 'Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException' error if I try to send the 38Mb file.
How can I fix this problem?
UPD
Thanks to phuzi - he wrote the link in the comments which helped to me to solve my problem.
I'm having trouble figuring out what's wrong with HttpClient script.
When I use Fiddler, it works & AspNetCore MVC isn't throwing errors.
http://localhost:6004/api/XUnitExamplesTest/JsonStringMethod
Http-Get
User-Agent: Fiddler
Accept: text/json
Content-Type: text/json
Host: localhost:6004
Content-Length: 24
"{\"Color\": \"Green\"}"
But HttpClient script causing AspNetCore MVC issues.
var sampleData = new XUnitSampleData() { Color = "Red" };
var contentType = "text/json";
var httpMethod = HttpMethod.Get;
var uriPath = "JsonStringMethod";
var jsonData = JsonConvert.SerializeObject(_sampleData, Formatting.None).ToString(); // JSON String. --> "{ \"Vin\" : \"foo\", \"Color\" : \"foo\" }"
var jsonRequest = string.Format("\"{0}\"", jsonData);
var result = await XUnitWebClient.GetAsync3(contentType, httpMethod, uriPath, jsonRequest, CancellationToken.None);
public static async Task<string> GetAsync3(string contentType, HttpMethod httpMethod, string uriPath, string request, CancellationToken cancellationToken)
{
using (var httpClient = new HttpClient())
{
using (var httpRequestMessage = new HttpRequestMessage(httpMethod, string.Format("{0}{1}", _uri, uriPath)))
{
httpClient.BaseAddress = new Uri(string.Format("{0}", _baseAddress));
//httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType)); // "Accept" Header.
//httpClient.DefaultRequestHeaders.Remove("Content-Type");
//httpClient.DefaultRequestHeaders.Add("Content-Type", contentType);
httpRequestMessage.Content = new StringContent(request, Encoding.UTF8, contentType); // "Content-Type" Header.
var response = await httpClient.SendAsync(httpRequestMessage);
return await response.Content.ReadAsStringAsync();
}
}
}
AspNetCore MVC got the JSON value as "{".
Since I'm using text/json so how do I tell HttpClient to send json string with beginning quote and ending quote, instead of it stripping that out?
Or am I doing something wrong with JsonConvert.SerializeObject() here?
To answer the question directly...
You're not escaping the quotes inside the JSON string. Try this:
var jsonRequest = string.Format("\"{0}\"", jsonData.Replace("\"", "\\\""));
However...
I question how you're approaching this problem. You mention in your comments that you get an error on the server side (in your MVC code) if you don't stringify the JSON on the client side. However, it is very awkward and non-standard to require the client to do this. I would:
Change the content type from text/json to application/json. That won't fix the problem, but it is the standard.
Remove the line above and send jsonData directly. i.e. don't stringify the JSON.
Ask a new question about how to solve the server-side error you're getting, and post the relevant MVC code.
I have created api project in .Net Core application. I have also created Method to accept HttpRequestMessage as parameter. Now I am trying to call my api method using Postman with including file as body parameter, but my api method is not calling.
Here is code
[Route("api/[controller]")]
public class ValuesController : Controller
{
[HttpPost]
public HttpResponseMessage PostFiles()
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Request;
return result;
}}
Here is Postman request data
POST /api/values/PostFiles HTTP/1.1
Host: localhost:64226
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 6adcc652-a4ab-3714-cc5e-770bd214ac7a
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"; filename=""
Content-Type:
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Here is the screen shot of my api call using postman.
Request body with file as parameter
Is there anything that I am missing?
Can you please help me out to call my web api with accepting file as parameter using Postman?
I think there's a problem with your route. Try this :
public class ValuesController : Controller
{
[Route("api/values/postfiles")]
[HttpPost]
public HttpResponseMessage PostFiles()
{
HttpResponseMessage result = null;
var files = Request.Form.Files;
return result;
}
}
Then try accessing the API at http://localhost:yourport/api/values/postfiles .
replace "yourport" in your port no.
You'll get the file in "fileStream" if the file is available.
In an ASP.NET Core application use IHostingEnvironment. Then you can call ContentRootPath and WebRootPath
I need to set charset ISO-8859-1 for the responses of my web api controllers, and not UTF-8.
The controller for testing returns a POCO object like this:
public class StudyCaseController : ApiController
{
...
// GET: api/StudyCase/5
public Study Get(int id)
{
...
}
}
I've tried to set <globalization requestEncoding="iso-8859-1" responseEncoding="iso-8859-1"/> in the Web.config, but testing with a fiddler request like this:
GET http://localhost:45988/api/StudyCase/1 HTTP/1.1
User-Agent: Fiddler
Host: localhost:45988
Accept: text/xml
I've got a response like this:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B? QzpcTUVESE9NRVxEZXNhcnJvbGxvQ1xQcm95ZWN0b3NcVmlld0NhcE1hblxWaWV3Q2FwTWFuXGFwaVxT dHVkeUNhc2VcMQ==?=
X-Powered-By: ASP.NET
Date: Tue, 24 Mar 2015 11:36:13 GMT
Content-Length: 1072
<?xml version="1.0"?>
... etc...
I've also tried to specify the charset at the request with Accept-Charset: iso-8859-1 but the same result.
For more info, i've tested it with IIS Express and IIS Server.
Thanks.
You can set supported encodings for formatters in HttpConfiguration class. 28591 is codepage for ISO-8859-1 (Latin 1).
config.Formatters.Add(new XmlMediaTypeFormatter());
config.Formatters[0].SupportedEncodings.Clear();
config.Formatters[0].SupportedEncodings.Add(Encoding.GetEncoding(28591));
Dealing with the problem my self, I found out that the problem was indeed the XML MediaTypeFormatter.
It does not support ISO-8859-1 and without the ability to change the server-side code I was forced to use another MediaTypeFormatter
https://www.nuget.org/packages/NetBike.Xml.Formatting/
or in nuget console
Install-Package NetBike.Xml.Formatting
This solved my problem (in a project using Web API 2).
Here is a demonstration of one way to set this using the HttpClient
private static HttpClient httpClient;
private static MediaTypeFormatter formatter;
private static List<MediaTypeFormatter> formatters;
public static void loadSettings()
{
//httpClient settings are set here
formatters = new List<MediaTypeFormatter>();
formatter = new NetBike.Xml.Formatting.NetBikeXmlMediaTypeFormatter();
formatters.Add(formatter);
}
public static async Task<HttpResponseMessage> GetContent(string requestMethod)
{
try
{
var returnValue = await httpClient.GetAsync(requestMethod);
return returnValue;
}
catch (Exception ex)
{
Debug.WriteLine("Communicator.GetXml: " + ex.Message);
}
return null;
}
public static async void testStuff()
{
var httpResponse = await GetContent("http://someDomain.com/someMethod");
MyModelObject myModel = await httpResponse.Content.ReadAsAsync<MyModelObject>(formatters);
}
What you want to do, is to set this as a default formatter for the whole project.
-EDIT-
Microsoft argues that this behavior is intended.
https://connect.microsoft.com/VisualStudio/feedback/details/958121
I have experienced issues with the NetBike Formatter, when formatting advanced XML objects, and even have a case where it writes BOM to the output.
Therefore I do not recommend it above the default MediaTypeSerializer, instead the solution falls back to the old "it depends"
That looks like this in code
List<MediaTypeFormatter> formatters = new List<MediaTypeFormatter>();
MediaTypeFormatter badencodingFormatter = new NetBike.Xml.Formatting.NetBikeXmlMediaTypeFormatter();
badencodingFormatter.SupportedEncodings.Clear();
badencodingFormatter.SupportedEncodings.Add(Encoding.GetEncoding("ISO-8859-1"));
MediaTypeFormatter defaultFormatter = new CustomXmlMediaTypeFormatter();
formatters.Add(badencodingFormatter);
formatters.Add(defaultFormatter);
This makes sure that anoying encoding is handled by NetBike, but only in those (hopefully rare) cases