0

I am attempting to send model and some attachments from an Angular 4.2.4 to a .Net 4.6 (MVC 4.0) Controller.

Sample models:

//JS model
{
 ID: number;
 Name: string
 NewAttachments: any
}

//.Net model
{
 int ID {get;set;}
 string Name {get;set;}
 HttpPostedFileBase NewAttachments {get;set;}
}

Working example: .Net takes the form just fine and populates the view Model

saveHealthForm(form: HealthFormModel): Observable<HealthFormModel> {
    let url = this.UPDATE_HEALTHFROM_URL;
    return this.http.post(url, form, this.HTTP_OPTIONS)
      .map(res => { 
       ...
      })
      .catch((error, caught): Observable<HealthFormModel> => {
          console.error(error);
          this.onError.emit(error);
          throw error;
      });
}


[HttpPost]
public JsonResult UpdateHealthForm(HealthFormViewModel viewModel)
{
    //view model is not null. 
    //view model contains no attachments.
    //this works great without attachments
}

Then I wanted to add attachments. First I thought I would just add attachments to the models. But found out I need to use FormData, so I separated them out and sent them as form data arguments.

saveHealthForm(form: HealthFormModel, files:FileList): Observable<HealthFormModel> {
    let formData: FormData = new FormData();
    formData.append("viewModel", JSON.stringify(data));

    if(files){
        for (let i = 0; i < files.length; i++) {
          formData.append(`files[]`, files[i], files[i].name);
        }
    }

    let url = this.UPDATE_HEALTHFROM_URL;
    return this.http.post(url, formData, this.HTTP_OPTIONS)
      .map(res => { 
       ...
      })
      .catch((error, caught): Observable<HealthFormModel> => {
          console.error(error);
          this.onError.emit(error);
          throw error;
      });
}

    [HttpPost]
public JsonResult UpdateHealthForm(HealthFormViewModel viewModel, IEnumerable<HttpPostedFileBase> files)
{
    //view model is null :(
    //files are null :(

    //it recieved the viewModel and the files, but i have to parse the viewModel out from json myself. :(
    var myForm = Request.Form.Get("viewModel")
    //im fine getting files this way, but the method param would be best. 
    var filewrapper = Request.Files.Get("files[]")
}

How can I use the 2 controller methods and have form data populate the method arguments?

Edit:

This makes it so that the model is not null. However none of the data populates correctly.

//formData.append("viewModel", JSON.stringify(data));
let formData: FormData = new FormData(data);

The attachments are located on the data object when it is passed to the FormData. However they are not in the model or passed as a method argument on the backend.

kosmos
  • 365
  • 7
  • 21
  • You cannot `.append()` a stringified object - you need to `.append()` each property of your object. And you need to set the correct ajax options. Refer [this answer](http://stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681) –  Nov 01 '17 at 13:11
  • you are correct on the first half, i was passing in the form incorrectly to the FormData in the JS, but Angular doesnt support files in its reactive forms solution, and my front end logic really is seperate from the form. I will test adding the files into the form. – kosmos Nov 01 '17 at 13:40

1 Answers1

0

Here is the service code you need to post to WebAPI:

upload(files, parameters){
    let headers = new Headers();
    let options = new RequestOptions({ headers: headers });
    options.params = parameters;
    return  this.http.post(this._baseURL + 'upload', files, options)
             .map(response => response.json())
             .catch(error => Observable.throw(error));

}

For more detail see the complete article here Angular 4 upload files with data

Ali Adravi
  • 21,707
  • 9
  • 87
  • 85
  • I'm not using WebAPI. Also, this solution is for sending files and no model, sending both is the challenge of this question. – kosmos Nov 01 '17 at 13:53