Передача файла CSV из Angular7 в MVC .Net Core - PullRequest
0 голосов
/ 19 февраля 2019

Я пытаюсь передать файл CSV своему бэкэнду, чтобы использовать библиотеку для анализа данных CSV.

У меня есть внешний интерфейс Angular7 с бэкендом C # .Net Core MVC, использующим HttpClient вмашинописный текст для передачи данных и объектов в и из серверной части.

Я пробовал несколько решений, но с минимальным успехом (самое близкое, что я могу добраться до контроллера в моем коде, но файл никогда

Я пытаюсь избежать какого-либо сериализации или преобразования CSV, пока он не попадет на контроллер, поэтому я бы хотел найти решение, в котором я мог бы отправить весь CSVна сервер.

Любая помощь будет оценена.

service.ts

// Parse CSV
// The CSV always reaches this part of the code and I can inspect it.
parseCsv$(file: File): Observable<Dto> {
    const request$ = this.http.post<Dto>(
        location.origin + '/api/csvimport',
        file,
        { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data' }) }
    ).pipe(
        map((response: <Dto>) => response)
    );

    request$.subscribe();

    return request$;
}

CsvImportController.cs

    [HttpPost]
    [ProducesResponseType(typeof(Dto), 200)]

    // The 'file' variable below is always null
    public async Task<IActionResult> ParseCsv([FromBody]IFormFile file)
    {
        // do work here

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Так что я смог понять это,

Мне нужно было изменить File на FileList, а затем использовать FormData, чтобы добавить файл.Мне также нужно было отбросить заголовок моего контента, так как он позволял бэкенду обрабатывать сам контент, предотвращая появление ошибок.В моем контроллере мне пришлось использовать IEnumerable<IFormFile>, чтобы это полностью работало.

Я не до конца понимаю, почему мне пришлось использовать FileList при загрузке только одного файла, но это былотребуется для отправки по файлу.Если я узнаю больше, я обновлю свой ответ.

РЕДАКТИРОВАТЬ: Обращаясь к вышесказанному, в документации MDN говорится, что "Все <input> элементузлы имеют атрибут файлов типа FileList, который позволяет получить доступ к элементам в этом списке " (https://developer.mozilla.org/en-US/docs/Web/API/FileList)). Таким образом, чтобы получить доступ к одному файлу, вам фактически необходим доступ к первому индексу (FileList[0]) массива FileList. Возможно, я неправильно понимаю, поэтому не стесняйтесь комментировать.

service.ts

parseCsv$(files: FileList): Observable<Dto> {
    const formData = new FormData();
    Array.from(files).forEach(
        (file: File) => formData.append(file.name, file)
    );

    return this.http.post<Dto>(
        location.origin + '/api/csvimport',
        formData)
    .pipe(
        map((response: <Dto>) => response)
    );
}

CsvImportController.cs

[HttpPost]
[ProducesResponseType(typeof(Dto), 200)]
public async Task<IActionResult> ParseCsv(IEnumerable<IFormFile> files)
{
    // Work here...
0 голосов
/ 19 февраля 2019

Вы не должны использовать параметр FromBody в File Upload.

Вы должны либо использовать, request.Form.Files collection , чтобы получить загруженный файл, ИЛИ

youможно использовать IList в действии контроллера, как показано ниже.

Ниже API получает список файлов, которые затем сохраняются во временной папке на сервере.

[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
    long size = files.Sum(f => f.Length);

    // full path to file in temp location
    var filePath = Path.GetTempFileName();

    foreach (var formFile in files)
    {
        if (formFile.Length > 0)
        {
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await formFile.CopyToAsync(stream);
            }
        }
    }

    // process uploaded files
    // Don't rely on or trust the FileName property without validation.

    return Ok(new { count = files.Count, size, filePath});
}

Надеюсь, это поможет.

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