5

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

2

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

3 Comments

what about viewmodel I want to pass? Cant get my head around it. I have successfully passed files and form data using params but I want to send json object with file. thx
I created these two models
public class Tutor{ public int ID {get;set;} public string Name {get;set;} } public class VM{ public VM(){ tutor = new Tutor(); } public List<IFormFile> files {get;set;} public Tutor tutor{get;set;} } for (var i=0;i<vm.files.length;i++) { data.append("files",vm.files[i].file); } var t={ ID :1,Name:"foo" }; data.append("tutor.ID", t.ID); data.append("tutor.Name", t.Name); $http.post("/api/FileUpload/",data,{ withCredentials:false, headers:{'Content-Type':undefined }, transformRequest:angular.identity, responseType:"arryabuffer" }) It mapped correctly.
1

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

Comments

1

You can try using formdata like so

const data = new FormData();

Then append your files and the json object

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);

Then post data.

On the server-side, create a method without any parameters, like

public async Task<ActionResult> Create() {
 // You can access the posted form object from Request.Form
 var vm = Request.Form;
 // your files
 var files = Request.Form.Files;
}

Request.Form is key value collection you can get anything you appended using the name. Name is the first argument in the append method of FormData.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.