error uploading a file to asp.net core app #433

Open
opened 2016-10-04 14:19:15 +00:00 by lucamorelli · 10 comments
lucamorelli commented 2016-10-04 14:19:15 +00:00 (Migrated from github.com)

In the constructor of the compoent I have this code:

    constructor(private fb: FormBuilder, private shared: SharedServices) {
        var URL: string = "/api/Allegati";
        this.uploader = new FileUploader({
            url: URL,
            headers: [{ name: 'Content-Type', value: 'multipart/form-data' }],
        });
    }

I add a few additonal fields to the form

        this.uploader.onBuildItemForm = (fileItem, form) => {
            form.append('titolo', this.allegato.Titolo);
            form.append('note', this.allegato.Note);
            form.append('entita', this.entita);
            form.append('entitaId', this.entitaId);
            return { fileItem, form }
        };

and clicking in a button I start the upload this way

this.uploader.queue[0].upload();

the upload is blocked by this exception

An unhandled exception has occurred while executing the request System.IO.InvalidDataException: Missing content-type boundary.

Am I missing something?

In the constructor of the compoent I have this code: ``` constructor(private fb: FormBuilder, private shared: SharedServices) { var URL: string = "/api/Allegati"; this.uploader = new FileUploader({ url: URL, headers: [{ name: 'Content-Type', value: 'multipart/form-data' }], }); } ``` I add a few additonal fields to the form ``` this.uploader.onBuildItemForm = (fileItem, form) => { form.append('titolo', this.allegato.Titolo); form.append('note', this.allegato.Note); form.append('entita', this.entita); form.append('entitaId', this.entitaId); return { fileItem, form } }; ``` and clicking in a button I start the upload this way ``` this.uploader.queue[0].upload(); ``` the upload is blocked by this exception ``` An unhandled exception has occurred while executing the request System.IO.InvalidDataException: Missing content-type boundary. ``` Am I missing something?
lucamorelli commented 2016-10-05 09:22:14 +00:00 (Migrated from github.com)

I think this is the problem

I compared two my app, one using angular 1 and one using angular 2 using chrome tools.
the angular component send this _Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryXAIXdwxDD9DS3PsV_ and it works,
the angular2 component send _Content-Type:multipart/form-data_ and doesn't work ( according chrome tools)
How can I fix it?

I think this is the problem I compared two my app, one using angular 1 and one using angular 2 using chrome tools. the angular component send this **_Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryXAIXdwxDD9DS3PsV**_ and it works, the angular2 component send **_Content-Type:multipart/form-data**_ and doesn't work ( according chrome tools) How can I fix it?
rousseauo commented 2016-11-09 15:05:55 +00:00 (Migrated from github.com)

@lucamorelli Did you found a solution ? I have the same problem.

@lucamorelli Did you found a solution ? I have the same problem.
jecourtney commented 2016-11-09 16:31:38 +00:00 (Migrated from github.com)

Hey guys, I also have the same problem. Is there a solution? If I take out the header, the error goes away, but no file is sent. BTW (update for asp.net core on the server code):

public async Task<ActionResult> Post(IList<IFormFile> files)
        {
            long size = 0;
            foreach(var file in files)
            {
                var filename = ContentDispositionHeaderValue
                                .Parse(file.ContentDisposition)
                                .FileName
                                .Trim('"');
                size += file.Length;
                var savePath = Path.Combine(_hostingEnvironment.WebRootPath, 'uploads', filename);  

                using (var fileStream = new FileStream(savePath, FileMode.Create))
                {
                    await file.OpenReadStream().CopyToAsync(fileStream);
                }

                return Created(savePath, file);
            }

            return BadRequest();
        }
Hey guys, I also have the same problem. Is there a solution? If I take out the header, the error goes away, but no file is sent. BTW (update for asp.net core on the server code): ``` public async Task<ActionResult> Post(IList<IFormFile> files) { long size = 0; foreach(var file in files) { var filename = ContentDispositionHeaderValue .Parse(file.ContentDisposition) .FileName .Trim('"'); size += file.Length; var savePath = Path.Combine(_hostingEnvironment.WebRootPath, 'uploads', filename); using (var fileStream = new FileStream(savePath, FileMode.Create)) { await file.OpenReadStream().CopyToAsync(fileStream); } return Created(savePath, file); } return BadRequest(); } ```
rousseauo commented 2016-11-09 20:06:10 +00:00 (Migrated from github.com)

In the end, I did not use any module to upload my files.
Here's how I did it:

In my Angular 2 component:

let fileUploadInput = $("#pictures").get(0);
let files:FileList = fileUploadInput .files;

let formData:FormData = new FormData();
for (var i = 0; i < files.length ; i++) {
  formData.append(files[i].name, files[i]);
}

let headers = new Headers();
headers.append('Accept', 'application/json');
// DON'T SET THE Content-Type to multipart/form-data 
// You'll get the Missing content-type boundary error
let options = new RequestOptions({ headers: headers });

this.http.post(this.baseUrl + "upload/", formData, options)
  .subscribe(r => console.log(r));

In my Dotnet Core API:

[HttpPost("upload")]
public async Task<IActionResult> PostUpload()
{
    var files = Request.Form.Files;

    foreach (var file in files)
    {
      var blobFile = await _fileProvider.SavePostedFile(file);
    }

    return Ok();
}
In the end, I did not use any module to upload my files. Here's how I did it: In my Angular 2 component: ``` let fileUploadInput = $("#pictures").get(0); let files:FileList = fileUploadInput .files; let formData:FormData = new FormData(); for (var i = 0; i < files.length ; i++) { formData.append(files[i].name, files[i]); } let headers = new Headers(); headers.append('Accept', 'application/json'); // DON'T SET THE Content-Type to multipart/form-data // You'll get the Missing content-type boundary error let options = new RequestOptions({ headers: headers }); this.http.post(this.baseUrl + "upload/", formData, options) .subscribe(r => console.log(r)); ``` In my Dotnet Core API: ``` [HttpPost("upload")] public async Task<IActionResult> PostUpload() { var files = Request.Form.Files; foreach (var file in files) { var blobFile = await _fileProvider.SavePostedFile(file); } return Ok(); } ```
Hotzilla commented 2017-06-13 07:05:13 +00:00 (Migrated from github.com)

ng2-file-upload works with latest ASP.NET core if you use:

        public IActionResult Upload(IFormFile file) {
		...
	}

It doesn't work if you use ICollection<IFormFile>. This of course means that the action is called multiple times if there is multiple files. No need to change any headers from angular side.

ng2-file-upload works with latest ASP.NET core if you use: ``` public IActionResult Upload(IFormFile file) { ... } ``` It doesn't work if you use `ICollection<IFormFile>`. This of course means that the action is called multiple times if there is multiple files. No need to change any headers from angular side.
JStepien90 commented 2017-06-24 07:58:00 +00:00 (Migrated from github.com)

It does not work if you expect any different params from routing:

[Route("api/{id}")]
public IActionResult Upload(int id, IFormFile file) {
...
}

It does not work if you expect any different params from routing: [Route("api/{id}")] public IActionResult Upload(int id, IFormFile file) { ... }
VahidN commented 2017-07-13 04:20:01 +00:00 (Migrated from github.com)

Here is a sample about how to use ng2-file-upload with ASP.NET Core

Here is a sample about how to use `ng2-file-upload` with ASP.NET Core - [the template](https://github.com/VahidN/angular-template-driven-forms-lab/blob/master/src/app/upload-file/ng2-file-upload-test/ng2-file-upload-test.component.html) - [the component](https://github.com/VahidN/angular-template-driven-forms-lab/blob/master/src/app/upload-file/ng2-file-upload-test/ng2-file-upload-test.component.ts) - [the controller](https://github.com/VahidN/angular-template-driven-forms-lab/blob/master/Controllers/SimpleUploadController.cs)
sergioprates commented 2018-07-29 14:33:44 +00:00 (Migrated from github.com)

Here works:

.NET Class

[Produces("application/json")]
   [Route("v1/[controller]")]
   public class ArquivoController : Controller
   {
       [Authorize("Bearer")]
       [HttpPost, DisableRequestSizeLimit]
       public async Task<IActionResult> Upload(List<IFormFile> arquivos)
       {
           return await Task.Run(() =>
           {
               //AssertionConcern.AssertArgumentNotNull(arquivos, "Parâmetro do request veio nulo");
               var boi = arquivos;
               var files = Request.Form.Files;

               return Ok();
           });
       }
   }

Angular method:

 public upload(rota: string, form: FormData): Promise<ResponseApi> {
       let headers: Headers = this.getTokenHeader();
       return this.http.post(URL_API_V1 + rota, form, new RequestOptions({headers: headers})
       ).map((resposta: Response, index: any)=>
       {
           return resposta.json();
       }).toPromise()
   }
Here works: .NET Class ``` [Produces("application/json")] [Route("v1/[controller]")] public class ArquivoController : Controller { [Authorize("Bearer")] [HttpPost, DisableRequestSizeLimit] public async Task<IActionResult> Upload(List<IFormFile> arquivos) { return await Task.Run(() => { //AssertionConcern.AssertArgumentNotNull(arquivos, "Parâmetro do request veio nulo"); var boi = arquivos; var files = Request.Form.Files; return Ok(); }); } } ``` Angular method: ``` public upload(rota: string, form: FormData): Promise<ResponseApi> { let headers: Headers = this.getTokenHeader(); return this.http.post(URL_API_V1 + rota, form, new RequestOptions({headers: headers}) ).map((resposta: Response, index: any)=> { return resposta.json(); }).toPromise() } ```
VahidN commented 2018-07-29 17:25:14 +00:00 (Migrated from github.com)

@sergioprates Don't use Task.Run in your action methods. It doesn't make it async. It's a fake async.

@sergioprates Don't use `Task.Run` in your action methods. It doesn't make it async. It's a fake async.
sergioprates commented 2018-07-30 12:44:18 +00:00 (Migrated from github.com)

@VahidN actually, I use TaskCompletionSource, Task.Run in this controller is only a test. And I think that it is discussion to another thread.

@VahidN actually, I use TaskCompletionSource, Task.Run in this controller is only a test. And I think that it is discussion to another thread.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dc/ng2-file-upload#433