Angular не может загружать файлы из .Net Core API - PullRequest
0 голосов
/ 21 мая 2019

Я использую Angular 6 для загрузки файлов .docx из API .Net Core 2.1 .

Код .Net Core ниже может напрямую получить файл .docx через URL в браузере после публикации в IIS.

Это ссылка, которую я использовал для устранения неполадок, поэтому я не думаю, что .Net Core не так:
Файл возврата в ASP.Net Core Web API

Когда я использую HttpClient для вызова API в Angular, тело будет пустым в ответе ...

.Net Core Controller

[HttpGet("[action]")]
public IActionResult DemoWordGet(string Custom, string Variety, string Type,
            string Brand, string ProductName, string Company = "test",
            string BeginDate = "2019-5-21", string EndDate = "2019-5-22")
{
    string DemoFile = _hostingEnvironment.ContentRootPath + @"\Templates\demo.docx";
    byte[] byteArray = System.IO.File.ReadAllBytes(DemoFile);
    MemoryStream memoryStream = new MemoryStream();

    memoryStream.Write(byteArray, 0, byteArray.Length);

    WordprocessingDocument document = WordprocessingDocument.Open(memoryStream, true);

    Body body = document.MainDocumentPart.Document.Body;

    Paragraph paragraph = body.AppendChild(new Paragraph());

    DocumentFormat.OpenXml.Wordprocessing.Run run = paragraph.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
    run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text("it is test context!"));
    document.Close();

    string FileName = "test-" + DateTime.Now.ToString("yyyyMMdd") + ".docx";
    memoryStream.Seek(0, SeekOrigin.Begin);

    return File(memoryStream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", FileName);
}

угловой компонент

this._printService.GetWord(printInfo).subscribe((response:any) => {
    const filename = response.headers.get('Content-Disposition').split(/[;'=]/).pop();
    saveAs(response.body, decodeURIComponent(filename))
});

Служба Angular API

GetWord(params: HttpParams): Observable<any> {
    return this.http.get<Blob>(
            `${this.apiUrl}/DemoWordGet`, 
            {   
                params,
                responseType: 'blob' as 'json',
                observe: 'response',
            });
}

Запрос и ответ хорошо отображались в браузере, однако подписанный ответ в console.log () ничего не показывает ...

https://imgur.com/a/VA04qiE

версия Chrome: 74.0.3729.157

----- Обновление -----

  1. Я вхожу в режим отладки и обнаруживаю, что тело ответа будет пустым до завершения подписки !!!

  2. Та же проблема есть и в Microsoft Edge.

  3. Я могу успешно загрузить файл, используя код ниже:

async test() {
    let res = await fetch(`${this.apiUrl}/DemoWordGet`, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/octet-stream',
        }
    });

    res.blob().then(x => {
        saveAs(x, 'test.docx');
    });
}

Это ошибка в HttpClient ??

Я до сих пор понятия не имею, что я делаю не так в Angular?

Ответы [ 2 ]

0 голосов
/ 21 мая 2019
 return this.http
    .get(`${this.apiUrl}/DemoWordGet`, {
      responseType: ResponseContentType.Blob
    })
    .map(res => {
      return {
        filename: 'filename.pdf',
        data: res.blob()
      };
    });

Это должен быть способ установить content-type для формирования blob

0 голосов
/ 21 мая 2019

Вы конвертируете свой BLOB-объект в json, что неверно, поэтому ваш код должен измениться с этого

responseType: 'blob' as 'json'

на этот

responseType: "blob"

И вы должны использовать createObjectUrl для загрузки файлакак это

downloadFile(data: Response) {
  const blob = new Blob([data], { type: 'text/csv' });
  const url= window.URL.createObjectURL(blob);
  window.open(url);
}
...