I'd like to use the ng2-file-upload component on the client side and everything works so far but now I have to pass an additional parameter with every file that contains an identifier the file is attached to. I try to set the additionalParameter property of the FileUploader object in TypeScript:
this.uploader.options.additionalParameter = {"issueId": result.data.id};
On the server I have the following method that is working except I don't get the additional parameter (issueId) set above. (.NET Core 2.0)
public RequestResultModel File(IFormFile file);
The request payload contains the parameter but in a new form-data:
------WebKitFormBoundaryegtYAcYfO3gKdk9Z
Content-Disposition: form-data; name="file"; filename="81980085.pdf"
Content-Type: application/pdf
------WebKitFormBoundaryegtYAcYfO3gKdk9Z
Content-Disposition: form-data; name="issueId"
19
------WebKitFormBoundaryegtYAcYfO3gKdk9Z--
How can I modify the controller method in order to read the issueId parameter as well? In a previous project I used a second parameter public async Task<ApiResultBase> Upload(IFormFile file, string projectid)
and it worked but now I would like to use this client side component because I don't want to suck with drag and drop and I'm lazy.
I have tried to change the component's POST url after initialize (this.uploader.options.url = "/api/Issue/File/"+result.data.id;
) but it tries to POST to the original address.
You are on track. I have a slightly different approach you can try out.On the client, try something like:
this.uploader = new FileUploader({
url: url,//The enpoint you are consuming
additionalParameter: {
issueId: result.data.id //your parameter-remove quotes
},
headers: [{ name: 'Accept', value: 'application/json' }],//your custom header
//autoUpload: true, //configure autoUpload
});
The library also has onErrorItem
and onSuccessItem
callbacks that you can leverage like below:
this.uploader.onErrorItem = (item, response, status, headers) => this.onErrorItem(item, response, status, headers);
this.uploader.onSuccessItem = (item, response, status, headers) => this.onSuccessItem(item, response, status, headers);
Then(Optional) - Callbacks:
onSuccessItem(item: FileItem, response: string, status: number, headers:ParsedResponseHeaders): any {
//this gets triggered only once when first file is uploaded
}
onErrorItem(item: FileItem, response: string, status: number, headers:
ParsedResponseHeaders): any {
let error = JSON.parse(response); //error server response
}
On the API side you can restructure like below - Change it to your own signature.
public async Task<IActionResult> UploadImages(MyFile upload)
Then the MyFile
model can be something like:
public class MyFile
{
public string issueId { get; set; }
public IFormFile File { get; set; }
}
To get the param and the file:
var file = upload.File //This is the IFormFile file
var param = upload.issueId //param
To save the file to disk:
using (var stream = new FileStream(path, FileMode.Create))
{
await file.File.CopyToAsync(stream);
}