Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File Upload with Form data in asp.net core

I am trying to upload files with form data from angular 1.5x to .net core web api controller. My controller looks like this

    [HttpPost]public async Task<ObjectResult> Create(TutorModel model) 
    {
    }

My post method is

 return $http.post("/api/Tutor/createTutor/",
      data,
                {
                    withCredentials: false,
                    headers: { 'Content-Type': undefined },
                    transformRequest: angular.identity,
                    responseType: "arryabuffer"
                });


Where data is


for (var i = 0; i < vm.uploadedFiles.length ; i++) { //vm.upload contains list of file
                data.append(vm.uploadedFiles[i].name, vm.uploadedFiles[i]);
            }
            data.append("tutor", tutor); //tutor is json object 

Now when it posts to controller, model contains no property value. I get uploaded files in controller if I watch Request.Form.Files. What is the best method of sending model to post method above. Any pointer? Thanks

like image 216
Aryan Avatar asked Dec 06 '16 09:12

Aryan


People also ask

How do I upload a multipart form data?

Multipart form data: The ENCTYPE attribute of <form> tag specifies the method of encoding for the form data. It is one of the two ways of encoding the HTML form. It is specifically used when file uploading is required in HTML form. It sends the form data to server in multiple parts because of large size of file.


2 Answers

Asp.net core documentation cover this topic briefly.

Your controller action would be like this.

[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
   long size = files.Sum(f => f.Length);

   // full path to file in temp location
   var filePath = Path.GetTempFileName();

   foreach (var formFile in files)
   {
      if (formFile.Length > 0)
      {
         using (var stream = new FileStream(filePath, FileMode.Create))
         {
            await formFile.CopyToAsync(stream);
         }
      }
    }

     // process uploaded files

    return Ok(new { count = files.Count, size, filePath});
}

Where IFormFile have these properties

   public interface IFormFile
   {
     string ContentType { get; }
     string ContentDisposition { get; }
     IHeaderDictionary Headers { get; }
     long Length { get; }
     string Name { get; }
     string FileName { get; }
     Stream OpenReadStream();
     void CopyTo(Stream target);
     Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
   }

Note: Use caution when storing binary data in relational databases, as it can adversely impact performance.

Read detail article here File Uploads

like image 148
Ahmar Avatar answered Oct 21 '22 12:10

Ahmar


One method to upload the Tutor would be to use JSON.stringify like this:

data.append("tutor", JSON.stringify(tutor));

Then in your action, parse the JSON string:

[HttpPost]
public async Task<IActionResult> Create([FromForm] string tutor) 
{
    var tutorObj = JsonConvert.DeserializeObject<TutorModel>(tutor);
}

You can upload the file in the same request if you convert your js to this:

 data.append("files", vm.uploadedFiles[i]);

Then add this to your action:

[FromForm] IEnumerable<IFormFile> files
like image 1
Shoejep Avatar answered Oct 21 '22 14:10

Shoejep