Search code examples
c#angulartypescriptform-dataangular-httpclient

Angular Frontend / C# API Backend - Post FormData (file) and Object


Hope someone can help me understand the process to upload the file (FormData) and an object from Angular to C# API. From what I understand, the HttpClient post method only accepts one body parameter, so I can post either the FormData object, or the SomeObject object, but not both. I have tried encapsulating SomeObject in FormData (using FormData.append), without success.

Angular frontend code snippet:

uploadAttachment(abcId: number, someObject: SomeObject)
{
  const url = this.apiUrl + '/abc/' + abcId;

  const formData = new FormData();
  formData.append('file', fileData);

  return this.http.post<ScopeItemAttachment>(url, formData, 
  {
    reportProgress: true,
    observe: 'events'
  });
}

C# API snippet:

[HttpPost("{abcID}", Name = "UploadAttachment")]
public IActionResult UploadAttachment(int abcId, SomeObject someObject)
{
    try
    {
        var file = Request.Form.Files[0];
        var temp = Request.Form.Keys;

        if (file.Length > 0)
        {
            fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');

            MemoryStream ms = new MemoryStream();
            file.CopyTo(ms);

            ms.Close();
            ms.Dispose();

            return Ok();
        }
        else
            return BadRequest(new { message = "File content length must be greater than zero" });
    }
    catch (Exception ex)
    {
        return StatusCode(500, $"Internal server error: {ex}");
    }
}

Solution

  • Assume that your SomeObject implementation is as below:

    public class SomeObject
    {
        public IFormFile File { get; set; }
    }
    
    1. Apply the [FromForm] attribute to the request body (someObject).

    2. You can get the file via someObject.File rather than Request.Form.File[0].

    [HttpPost("{abcId}", Name = "UploadAttachment")]
    public IActionResult UploadAttachment(int abcId, [FromForm] SomeObject someObject)
    {
    
        var file = someObject.File;
    
        ...
    }