如何在Angular POST正文中包含FormData以IFormFile从ASP.NET Core后端检索它

时间:2019-06-20 10:18:40

标签: c# angular http asp.net-core

我需要通过POST请求从Angular的前端发送文件(图像)以及其他一些参数到我的ASP.NET Core后端,以将文件上传到服务器。问题是我可能会收到HTTP 500错误,具体取决于我指定的标头,或者最常见的是,后端将FormData接收为空对象。

在Angular中,我首先将收到的Base64图像转换为Blob,然后将其转换为构造FormData的文件(这是ngx-compress-image包在压缩图像时返回的内容。也许有更好的方法这个也是?)。然后我分配标题并发送POST请求:

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

后端:

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

            ...
    }
}

编辑 好的,所以我应用了Tony的解决方案,但是起初没有奏效。经过一些测试,我找到了解决方案,如Nishant建议的那样将IFormFile变量声明为List,并使用[FromForm]声明每个参数,如下所示:

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

但是我仍然有一个问题,因为事实证明我的IFormFile具有ContentType:application / octet-stream 我不知道这是否是平常的,我必须将其从后端转换为某种图像内容类型或类似的内容,或者它是否应该像我在Angular Blob中声明的那样以图像/ png的形式来自于POST请求文件。

Variable screenshot

再次感谢大家,希望您仍然可以帮助我解决上一期问题。

3 个答案:

答案 0 :(得分:1)

您还必须像这样使用FormData作为对象

expected zero arguments for construction of ClassDict (for numpy.dtype)

还必须在控制器中使用[FromForm]

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

答案 1 :(得分:0)

两个网址都不匹配。

答案 2 :(得分:0)

我已经使用IFormFile接口完成了

  

string emailModel是要反序列化的Model

     

用于附件列表的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();
}