Tips on utilizing FormData in Angular POST request to pass data to ASP.NET Core Backend and extract it as IFormFile

I'm facing a challenge where I need to transmit an image file from the frontend developed in Angular, along with additional parameters, using a POST request to my ASP.NET Core backend for file upload to a server. However, I'm encountering issues such as receiving an HTTP 500 Error based on the headers I set, or more commonly, the backend receiving an empty object when FormData is sent.

In my Angular code, I convert the Base64 image into a Blob, and then into a File to create the FormData object (this is the format returned by the ngx-compress-image package for image compression). I'm wondering if there might be a better approach to achieve this. After constructing the FormData object, I set the headers and initiate the POST request:

export class RestApiService {
    token: string = 'The session token';
    userID: string = 'The user ID';

    UploadImage(picAsBase64: string) {
        let blob = new Blob([picAsBase64], { type: 'image/png' });
        let file = new File([blob], Math.random().toString(36).substr(2, 5));

        let formData: FormData = new FormData();
        formData.append('pfile', file);

        const headers = new HttpHeaders({
          'Content-Type': 'multipart/form-data',
          'Accept': 'application/json'
        });

        let options = { headers: headers };

        let body = {
          'paramh': this.token,
          'pfile': formData,
          'pkuserid': this.userID
        }

        return this.http.post('api/UploadFiles/UploadFiles/', body, options).pipe(map(data => { return data; }));
    }
}

Backend:

[Route("api/[controller]")]
public class UploadFilesController : Controller
{
    [HttpPost("UploadFiles")]
    public async Task<IActionResult> UploadFiles([FromBody]JObject data)
    {
        string paramh = data["paramh"].ToString();
        IFormFile pfile = data["pfile"].ToObject<IFormFile>();
        string pkuserid = data["pkuserid"].ToString();

            ...
    }
}

EDIT I followed Tony's solution, but initially encountered issues. After some experimentation, I found success by declaring the IFormFile variable as a List as suggested by Nishant and using [FromForm] for each argument, like this:

public async Task<IActionResult> UploadFiles([FromForm]string paramh, [FromForm] string pkuserid, [FromForm]List<IFormFile> pfiles)

However, I'm facing another problem where my IFormFile has the ContentType set as application/octet-stream. I'm unsure if this is standard behavior and if I need to convert it to an image content type on the backend, or if it should be received in the POST request as image/png, as declared in the Angular Blob before creating the file.

Variable screenshot

Thank you all for your help, and I'm hopeful that you can assist me in resolving this final issue.

Answer №1

Ensure to utilize FormData for your object in the following manner:

    const formData: FormData = new FormData();
    formData.append('pfile', file);
    formData.append('paramh', this.token);
    formData.append('pkuserid', this.userID);
    return this.http.post('api/UploadFiles/UploadFiles/', formData, options).pipe(map(response => { return response; }));

Additionally, include [FromForm] in your controller code:

 public async Task<IActionResult> UploadFiles([FromForm]JObject data)

Answer №2

Neither of the links are aligning.

Answer №3

I have successfully implemented this functionality using the IFormFile interface

The emailModel variable will store the deserialized Model

The files variable will store a list of attachments using IFormFile

[HttpPost]
public async Task<IActionResult> SendEmailAsync(string emailModel, List<IFormFile> files)
{
    EmailModel emailModel = JsonConvert.DeserializeObject<EmailModelWith>(emailModel);
    List<Attachment> attachments = new List<Attachment>();
    foreach (var file in files)
    {
         Attachment attachment = new Attachment(file.OpenReadStream(), file.FileName, file.ContentType);
         attachments.Add(attachment);
    }
    return Ok();
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Replace the JSON with PHP data when the fields match

I am currently working on a project that involves writing to a json file. I would like to be able to overwrite an object in the file if certain fields match. The code I have retrieves the data from the JSON file, but it simply adds the latest object to the ...

Localizing your Angular 2 application with multiple languages

I'm currently working on localizing my Angular 2 app based on the browser's language settings. I send a POST request to my database to retrieve translations for the specified language in the header. Current Implementation: I have a shared varia ...

Tips for properly importing types from external dependencies in TypeScript

I am facing an issue with handling types in my project. The structure is such that I have packageA -> packageB-v1 -> packageC-v1, and I need to utilize a type declared in packageC-v1 within packageA. All the packages are custom-made TypeScript packa ...

Convert JSON data into jQuery format, then present it in a list format using `<ul>` and

After making an ajax request, I receive a JSON string containing error messages regarding required form fields: first name, last name, email, usercode, password, password confirmation, and captcha. { "first_name":["The first name field is required."], " ...

Obtain values from a specific set, and then filter out values from an array that correspond to the index of that set into distinct arrays

The Problem I'm Facing Currently, I am dealing with a large data table that contains a mix of relevant and irrelevant data. My goal is to filter out the information I care about and display it in a more concise table. Using RegEx, I have managed to i ...

Efficiently comparing an IEnumerable<T> to an IEnumerable<IEnumerable<T>>

I am working with two IEnumerable collections in C#, one containing instances of MyClass1 and the other containing instances of MyClass2, which has a function returning MyClass1 objects. Here is an example: IEnumerable<MyClass1> list1; IEnumerable&l ...

Guide on making a custom JSON class in Kotlin specifically for Fuel

My current issue involves a request that returns JSON: { "success": 0, "errors": { "phone": [ "Incorrect phone number" ] } } In my Kotlin code, I mistakenly used Fuel instead of Retrofit. This led to the creation of the following clas ...

Determine whether the value from a JSON is a boolean (either true or false)

I have encountered an issue while trying to code a category on NSManagedObject. The goal is to allow the object to populate its attributes from a dictionary obtained through JSON using NSJSONSerialization. The problem I'm facing is that when the orig ...

index signature in TypeScript is an optional feature

Is it possible to create a type with optional namespaces in TypeScript? export interface NodesState { attr1: number; attr2: number; attr3: number; } The goal is to allow users to namespace the type like this: { namespace1: { attr1: 100, ...

Fetch data in JSON format from a specified URL

I have been attempting to fetch a JSON from a specific URL. Here is my current code snippet: <script> var co2; $(document).ready(function(){ alert("0"); $.getJSON(url,function(result){ var jsonObject = result; alert(result); ...

Issue with calling jQuery method from the view in C# not executing the function as expected

I am trying to implement jQuery in a view, but I am facing an issue where the backend method is not being triggered as expected. I need some additional eyes to help me figure out why it's not working properly. <script src="../Scripts/jquery-1.7.1. ...

Using Angular to show information in a textarea box from a service

Recently, I picked up Angular and worked on the tour-of-heroes app. Currently, I'm facing a challenge in displaying a set of steps in a textarea based on the selected hero. The idea is that when hero1 is selected, it should show step 1, and upon click ...

Can you explain how to break down secured routes, users, and posts all within a single .create() function in Mongoose/JavaScript

I am seeking guidance on utilizing the .create() method within a protected route while implementing deconstructed JavaScript. In the absence of the protected route, I can deconstruct my schema and utilize req.body in .create(...) as shown below. const { ti ...

Question about datalist in ASP.NET

This morning, I spent some time working on the DataList and UserControl and made progress. However, I am still trying to figure out how to enhance my code since everything is functioning but the GUI is not yet as desired. Within the ASPX file, I have the ...

transmitting a set of 4 parameters within a single object or an array of objects in the REST API

Currently, I am in the process of learning about RestAPI and I have a query. Is it possible to send 4 parameters in one object as a response? Here is the code snippet: return response()->json(['success'=>true,'message'=>&apo ...

There was an error with JSON parsing in the fetch request due to an unexpected character found at line 1, column 2 of the JSON data

Currently, I am diving into learning JavaScript and the fetch API. As part of my practice, I am trying to retrieve exchange rate data from an API endpoint provided by a bank. However, I'm facing difficulties in parsing the response body into JSON form ...

Strategies for enhancing efficiency in managing numerous service methods

I have developed a menu verification system that checks for product availability on each server. If a server does not have any products, the corresponding menu is hidden. My approach involves: Creating a service to check the products in each menu. Running ...

Troubleshooting: Vue and TypeScript Components Not Communicating

Vue is still fairly new to me and I'm struggling with this issue. Despite following code examples, my implementation doesn't seem to be working correctly. The component I defined looks like this: <template> <div class="row"> ...

The requested resource does not have an 'Access-Control-Allow-Origin' header

- ISSUE: The XMLHttpRequest to 'https://*.execute-api.*.amazonaws.com/api' from 'http://localhost:4200' is blocked by CORS policy. The preflight request doesn't have the necessary 'Access-Control-Allow-Origin' header. ...

Comprehensive compilation of Typescript error codes along with solutions

Where can I find a comprehensive list of Typescript error codes and their corresponding fixes? I frequently encounter errors during compilation, such as: data_loader_service.ts(10,13): error TS1005: '=>' expected. data_loader_service.ts(10,24 ...