Request.Form.Files' threw an exception of type 'system.invalidoperationexception' with Incorrect Content Type 'application-json' in asp.net core 2.2

Viewed 5162

I am using asp.net core 2.2 with angular 8. I am trying to upload files with some data to be saved using post method. Data is passing to controller but in controller Request.Form object is throwing error.

It was working properly in asp.core 2.0 with angular 2. But I am trying to update this project to angular 8 with asp.net core 2.2. Now I am getting this error "Request.form.files' threw an exception of type 'system.invalidoperationexception'".

Angular Service Code:

        saveNewMail(user: CommunicationActivityModel, files: File[]) {
        let body = JSON.stringify(user);
        let formData = new FormData();
        for (var i = 0; i < files.length; i++) {
          formData.append('uploadedFiles', files[i]);
        }
         formData.append('user', body);

         let requestedUrl = this.baseUrl + 'SaveNewMail';

         return this.apiService.postFormData(requestedUrl, 
         formData).pipe(map(response => response));

   }

api.service Code:

 postFormData(path: string, body: FormData): Observable<any> {
    return this.http.post(
      `${environment.api_url}${path}`,
       body
     ).pipe(catchError(this.formatErrors));
  }

Controller Code:

        [HttpPost]
        [Route("SaveNewMail")]
        public IActionResult SaveMail()
       {
            var files = Request.Form.Files;
            var communicationActivityString = Request.Form["user"];
            var communicationActivity = 
    JsonConvert.DeserializeObject<CommunicationActivityViewModel> 
   (communicationActivityString);
            var activityId = 
    _messageCenterService.SaveNewMail(communicationActivity, files);
                return Ok(activityId);
            }
2 Answers

I had a HttpTokenInterceptor class which added the following config for every Http request.

 headersConfig = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  };

But for Request.Form.Files, you have to skip this json config. So I created a custom metadata class.

export class InterceptorMetaOptions {
  constructor(
    public skipIncerceptor: boolean = false,
    public skipJson: boolean = false,
    public skipAuthorization: boolean = false
  ) { }
}

And passed it in http request.

saveNewMail(user: CommunicationActivityModel, files: File[]) {

let body = JSON.stringify(user);
let formData = new FormData();
for (var i = 0; i < files.length; i++) {
  formData.append('uploadedFiles', files[i]);
}
formData.append('user', body);

let requestedUrl = this.baseUrl + 'SaveNewMail';

let options = {
  headers: {
    meta: [new InterceptorMetaOptions(false, true, false)]
  }
};

return this.apiService.postFormData(requestedUrl, formData, options).pipe(map(response => response));

}

And checked it in HttpTokenInterceptor class to skip the json config.

intercept(request: HttpRequest<any>, next: HttpHandler): 
Observable<HttpEvent<any>> {

var customMetaOption = this.getMeta(request);

if (customMetaOption) {
  console.log("Custom Meta Applied");
  console.log(customMetaOption);
}

let headersConfig = {};

if (!customMetaOption || !customMetaOption.skipJson) {
  headersConfig = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  };
}


const req = request.clone({ setHeaders: headersConfig });

I had the same problem, and solved it like this:

HttpPost("upload")]
public string Add([FromForm]IFormFile file)
{ ... }

And the postman request: Header Postman-Token: 27842313-1362-40fb-8076-427e38b96502 Host: localhost:5102 Content-Type: multipart/form-data; boundary=--------------------------347717672664685938315818 Content-Length: 109286

Body

Related