简体   繁体   中英

How to include FormData in Angular POST body to retrieve it from ASP.NET Core Backend as IFormFile

I need to send a File (image) from the frontend in Angular along with some more parameters via a POST request to my ASP.NET Core backend to upload the file to a server. The issue is that I either get an HTTP 500 Error depending on the headers I specify or, the most usual, the backend receives the FormData as an empty object.

In Angular, I first convert the Base64 image I receive to a Blob, then a File to construct the FormData (it's what the ngx-compress-image package returns when it compresses an image. Maybe there is a better way to do this too?). Then I assign the headers and send 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 Okay, so I applied Tony's solution, but it didn't work at first. After some tests, I found the solution in declaring the IFormFile variable as a List like Nishant suggested and declaring every argument with [FromForm] like so:

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

BUT I still have an issue, because it turns out that my IFormFile has ContentType: application/octet-stream I don't know if this is the usual and I must convert it from the backend to some image contenttype or something like that, or if it should come from the POST request as an image/png like I declared in the Angular Blob before creating the file.

Variable screenshot

Thank you all again and hope you can still help me with this last issue.

You have to use FormData for your object also like this

    let 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(data => { return data; }));

Also you have to use [FromForm] in your controller

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

两个网址都不匹配。

I have done it by using IFormFile interface

string emailModel is the Model which will be deserialized

List of IFormFile files for the list of attachments

[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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM