Http post a file data - html

I have two <input> tag on my client to choose a file. Once the client choose the files (24-bit BMP 640*480), I have to make a http.post so that I could save the imageData of each file and make a http.get when I need it. I tried posting an ImageData object or just an Uint8ClampedArray but I was getting some errors. Now I tried to convert it to base64 and send it but I'm still not getting anything.
This is my http.post:
public submitInfo(): void {
this.http.post("http://localhost:3000/sologame", { "name": this.game.gameName, "image1": this.game.picture }, HTTP_OPTIONS).pipe(
catchError(this.handleError("submitInfo"))).subscribe();
}
This is the error I'm getting now that I'm trying to send a base64 string:
How can I send the data of my image?

There is two way to do it:
Send binary data
onUpload(selectedFile: File) {
this.http.post('api/file-upload', selectedFile).subscribe(...);
}
Send as FormData
onUpload(selectedFile: File) {
const uploadData = new FormData();
uploadData.append('file', selectedFile, selectedFile.name);
this.http.post('api/file-upload', uploadData).subscribe(...);
}

Related

.NET Core - How to upload JSON file?

I am trying to upload JSON file in order to read values from it and save them in database, but I have problem with that. Code of my controller looks as following:
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class ImportController : ControllerBase
{
private readonly DatabaseContext dbContext;
public ImportController(DatabaseContext dbContext)
{
this.dbContext = dbContext;
}
[HttpPost]
public IActionResult ImportData(IFormFile file)
{
var content = string.Empty;
using (var reader = new StreamReader(file.OpenReadStream()))
{
content = reader.ReadToEnd();
}
List<UserModel> userObjects = null;
try
{
userObjects = JsonConvert.DeserializeObject<List<UserModel>>(content);
}
catch
{
return BadRequest();
}
foreach (var user in userObjects)
{
UserModel us = new UserModel
{
Username = user.Username,
Password = user.Password
};
dbContext.User.Add(us);
dbContext.SaveChanges();
}
return Ok();
}
}
I'm using Postman to send JSON data, but anytime I try to do it, I get following response:
{"Username":["The input was not valid."]}
when I try to send JSON data as raw->application/json OR
{"":["The input was not valid."]}
when I try to send it by form-data with key called "file" and test.json file as value.
Could you direct me to the right path? I tried to use [FromBody] UserModel user as parameter of my action, but it only allows me to process one JSON string.
You can use [FromBody] IEnumerable<UserModel> users to process many rows. In this case json should look like:
[
{
"userName": "name",
"password": "password",
},
{
"userName": "name1",
"password": "password1",
}
]
You need to standardize your approach one way or another. If you want to accept JSON, then bind to an action param of type List<UserViewModel> with the [FromBody] attribute, and client-side, use JavaScript's FileReader to get the actual content of the upload loaded file and post the content, rather than the file.
If you want to do it by file upload, then you can keep the action as it is, but you'll need to then send your own "JSON" as a file upload as well. This can be achieved by using FormData in JavaScript and creating a Blob manually from your JSON object as a string.
Long and short, whichever path you choose, be uniform about it. There's no way to handle both posting a JSON object and a file upload that happens to be a text file with a .json extension in the same action.
I resolved it... All I had to do was deleting [ApiController] attribute. Having that attribute caused application to didn't visit my ImportData method at all.

Retrieving binary file from post request

Sending a POST request (Apache httpclient, here Kotlin source code):
val httpPost = HttpPost("http://localhost:8000")
val builder = MultipartEntityBuilder.create()
builder.addBinaryBody("file", File("testFile.zip"),
ContentType.APPLICATION_OCTET_STREAM, "file.ext")
val multipart = builder.build()
httpPost.entity = multipart
val r = httpClient.execute(httpPost)
r.close()
I receive the request in my post handler as a via spark-java Request-object. How do I retrieve the original file (plus the file name as a bonus) from the post request? The request.bodyAsBytes() method seems to add some bytes because the body is larger than the original file.
Thanks, Jörg
Near the bottom of Spark's Documentation page there is a section "Examples and FAQ". The first example is "How do I upload something?".
From there, it links further to an example on GitHub.
In short:
post("/yourUploadPath", (request, response) -> {
request.attribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement("/temp"));
try (InputStream is = request.raw().getPart("file").getInputStream()) {
// Use the input stream to create a file
}
return "File uploaded";
});
To access the original file name:
request.raw().getPart("file").getSubmittedFileName()
To handle multiple files or parts, I usually have code similar to the following (assuming only files are included in the multi-part encoded upload):
for (Part part : req.raw().getParts()) {
try (InputStream stream = part.getInputStream()) {
String filename = part.getSubmittedFileName();
// save the input stream to the filesystem, and the filename to a database
}
}

ReactJS: Unable to send JSON data and PDF file in one POST call

I am working on GRAILS-ReactJs based project which involves a scenario where I need to send the RESUME and the JSON data in one POST call.
However, I am able to send file in one call but the data I am getting is null.
I am using Grails-3 at my server side and receiving the POST request as multipart file. I want both JSON and Multipart file object to be combined in one object to send to the server and want to receive the file and the JSON data both at the server side.
I have tried changing the content type of the header but ut doesn't work.
You can't post JSON data along with the file or any other attachment. You can post it as form data to your back end. The form data is passed as a multi-part data to the server with relevant boundaries. Here's a sample code for your reference. You may pass json data along with the formData as key, value pairs.
export function postAttachment (fileData, fileName) {
let formData = new FormData()
formData.append('prop1', 'value1')
formData.append('prop2', 'value2')
formData.append('upload', fileData, fileName)
return fetch('/your/endpoint', {
headers: {
'Accept': 'application/json',
'header1': 'headerValue1'
},
method: 'POST',
body: formData
})
}
Hope this helps. Happy Coding !

Parse and convert xls file (received from GET request to URL) to JSON without writing to disk

The title says everything.
I want to get an xls file from a third party server. (said service keeps fueling
records, and they do not expose any kind of api, only the excel file).
Then parse that file with a library like node-excel-to-json, and convert it into JSON format I can use to import the data in mongo.
I want to manipulate the file in-memory, without writing it to disk.
So, say I am getting the file with this code,
parseFuelingReport() {
let http = require('http');
let fs = require('fs');
// let excel2Json = require('node-excel-to-json');
let file = fs.createWriteStream("document.xls");
let request = http.get("http://www.everydayexcel.com/files/Excel_Test_Basic_1_cumulative_sum.xls", function (response) {
});
},
I want to load the response in memory and parse it with something like
excel2Json(/* this is supposed to be the path to the xls file */, {
'convert_all_sheet': false,
'return_type': 'File',
'sheetName': 'survey'
}, function (err, output) {
console.log('err, res', err, output);
});
I assume you are using https://github.com/kashifeqbal/node-excel-to-json, which is available as node package.
If you take a look at this line,
you can see, two things:
It calls XLSX.readFile(filePath);, what will load a file from disk. Hard to call with an in-memory object in.
Internally it uses a XLSX package, most likely this one: https://www.npmjs.com/package/xlsx
The XLSX API seems not as convenient as the excel2Json, but it provides a read() function which takes a JavaScript object:
/* Call XLSX */
var workbook = XLSX.read(bstr, {type:"binary"});
Hope this helps

File upload to Web API using Multipart request

I have a Silverlight application that uses Web API to upload a document that is stored in a Database as a Filestream. Currently it's done by a POST with a Content-Type: application/json. The object containing a byte array of the File along with some metadata about the file is serialized to JSON and posted to the Web API. Web API then saves the byte array as a Filestream to the Database.
Following is a sample of the current request:
{"FileContent":"JVBERi0xLjUNJeLjz9MNCjEwIDAgb2JqDTw8L0xpbmVhcml6ZWQgMS9MIDI3MTg2L08gMTIvRSAyMjYyNi9OIDEvVCAyNjg4NC9IIFsgNDg5IDE2OF0+Pg1lbmRvYmoNICAgICAgICAgICAgICAgICAgDQoyNyAwIG9iag08PC9EZWNvZGVQYXJtczw8L0NvbHVtbnMgNC9QcmVkaWN0b3IgMTIg0K","ProductId":"85c98324-092a-4d10-bab0-03912e437234","OrderId":"7b826322-7526-4a69-b67c-5c88a04f4c60","FileName":"test.pdf","FileType":1,"FileDescription":"test"}
I would like to change this logic to Post as a Content-Type of Multipart. What would be the best way to form my request? Also, what's the best way to structure my Web API Controller to process the Multipart request?
This is a sample for a Multipart upload.
[HttpPost]
[Route("upload")]
public async Task<IHttpActionResult> Upload()
{
MultipartFileData file = null;
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
return UnsupportedMediaType();
}
// initialize path and provider
string root = HttpContext.Current.Server.MapPath("~/App_Data");
if (Directory.Exists(root) == false) Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
try
{
// we take the first file here
file = provider.FileData[0];
// and the associated datas
int myInteger;
if (int.TryParse(provider.FormData["MyIntergerData"], out myInteger) == false)
throw new ArgumentException("myInteger is missing or not valid.");
var fileContent = File.ReadAllBytes(file.LocalFileName);
// do something with your file!
}
finally
{
// get rid of temporary file
if (file != null)
File.Delete(file.LocalFileName);
}
// successfull!
return NoContent();
}
This is a sample I got from an API of mine. You can have multiple files for each upload (check the provider.FileData array), and different datas inside the provider.FormData array.
For the client side aspect of this I suggest you to check this answer for a sample of a JS call to this API.
Hope it helps!