Как включить FormData в тело Angular POST, чтобы извлечь его из базового бэкэнда ASP.NET как IFormFile - PullRequest
1 голос
/ 20 июня 2019

Мне нужно отправить файл (изображение) из внешнего интерфейса в Angular вместе с некоторыми другими параметрами через POST-запрос к моей серверной части ASP.NET Core, чтобы загрузить файл на сервер. Проблема в том, что я либо получаю ошибку HTTP 500 в зависимости от указанных мной заголовков, либо, как правило, бэкэнд получает FormData как пустой объект.

В Angular я сначала преобразовываю полученное изображение Base64 в Blob, затем в File для создания 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; }));
    }
}

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 Итак, я применил решение Тони, но сначала оно не сработало. После некоторых тестов я нашел решение объявить переменную IFormFile в виде списка, как предложил Nishant, и объявить каждый аргумент с помощью [FromForm] следующим образом:

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

НО У меня все еще есть проблема, потому что оказывается, что у моего IFormFile есть ContentType: application / octet-stream Я не знаю, является ли это обычным делом, и я должен преобразовать его из серверной части в некоторый тип содержимого изображения или что-то в этом роде, или если он должен исходить из запроса POST как image / png, как я объявил в Angular Blob перед созданием файл.

Скриншот переменной

Еще раз спасибо всем и надеюсь, что вы все еще можете помочь мне с этим последним вопросом.

Ответы [ 3 ]

1 голос
/ 20 июня 2019

Вы должны использовать FormData для вашего объекта, также как это

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

Также вы должны использовать [FromForm] в вашем контроллере

 public async Task<IActionResult> UploadFiles([FromForm]JObject data)
0 голосов
/ 20 июня 2019

Я сделал это с помощью интерфейса IFormFile

string emailModel - модель, которая будет десериализована

Список файлов 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();
}
0 голосов
/ 20 июня 2019

Оба URL не совпадают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...