如何使用 asp.net 核心 3.1 Web API 返回带有打开 API 的文件 客户端为打字稿(角度)生成的代码



这是问题所在。我有一个使用 DinktoPdf 生成 pdf 的 web api 方法,我想将其返回到角度客户端并将其显示在弹出式 pup 上,但似乎无法打开它。这是我的 API 的代码:

[HttpGet("PrintGravimetricSheetReport")]
[SwaggerOperation(OperationId = "PrintGravimetricSheetReport")]
[SwaggerResponse(200, "Ok", typeof(File))]
[SwaggerResponse(400, "Bad Request", typeof(ErrorResponse))]
public async Task<IActionResult> PrintGravimetricSheetReport()
{
var vm  = new QuoteLineItemModel();
var documentContent = await _templateService.RenderTemplateAsync("GravSheet", vm);
string folderPath = _hostEnvironment.ContentRootPath + "\GeneratedDocs\GravSheets\";
if (!Directory.Exists(folderPath))
Directory.CreateDirectory(folderPath);
var fileName = folderPath + "GravSheet_Report.pdf".AppendTimeStamp();

var globalSettings = new GlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
Margins = new MarginSettings(){Top =10},
DocumentTitle = "GravSheet Report",
Out = fileName
};
var objectSettings = new ObjectSettings
{
PagesCount = true,
HtmlContent = documentContent,
WebSettings = { DefaultEncoding = "utf-8" },
HeaderSettings = { FontName = "Arial", FontSize = 9, Right = "Page [page] of [toPage]", Line = true},
FooterSettings = { FontName = "Arial", FontSize = 9, Line = true, Center = "Report Footer"}
};
var pdf = new HtmlToPdfDocument
{
GlobalSettings = globalSettings,
Objects = {objectSettings}
};
var file = _converter.Convert(pdf);
return File(file, "application/pdf");
}

正如你在那里观察到的,我正在使用swagger来记录我的api,并且我还使用Open-Api为Angular客户端生成打字稿客户端。 这是自动生成的代码:

import { Inject, Injectable, Optional }                      from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams,
HttpResponse, HttpEvent, HttpParameterCodec }       from '@angular/common/http';
import { CustomHttpParameterCodec }                          from '../encoder';
import { Observable }                                        from 'rxjs';
import { ErrorResponse } from '../model/errorResponse';
import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
import { Configuration }                                     from '../configuration';

@Injectable({
providedIn: 'root'
})
export class ReportsService {
protected basePath = 'http://localhost';
public defaultHeaders = new HttpHeaders();
public configuration = new Configuration();
public encoder: HttpParameterCodec;
constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
if (configuration) {
this.configuration = configuration;
}
if (typeof this.configuration.basePath !== 'string') {
if (typeof basePath !== 'string') {
basePath = this.basePath;
}
this.configuration.basePath = basePath;
}
this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
}

/**
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public printGravimetricSheetReport(observe?: 'body', reportProgress?: boolean): Observable<object>;
public printGravimetricSheetReport(observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<object>>;
public printGravimetricSheetReport(observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<object>>;
public printGravimetricSheetReport(observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
let headers = this.defaultHeaders;
// to determine the Accept header
const httpHeaderAccepts: string[] = [
'text/plain',
'application/json',
'text/json'
];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}

return this.httpClient.get<object>(`${this.configuration.basePath}/api/Reports/PrintGravimetricSheetReport`,
{
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
}
}

这是我尝试在客户端中打开 api 返回的对象:

printGravSheet(): void {
this.reportService.printGravimetricSheetReport().subscribe(response => {
const blob = new Blob([response], { type: 'application/pdf' });
const url = window.URL.createObjectURL(response);
const showWindow = window.open(url);
if (!showWindow || showWindow.closed || typeof showWindow.closed === 'undefined') {
alert('Please disable your Pop-up blocker and try again');
}
});
}

只需从中获取错误消息即可。请有人指出正确的方法。提前谢谢。

所以环顾四周,我发现你需要删除 web api 上的行:

Out = fileName

Web API 最终版本为:

[HttpGet("PrintGravimetricSheetReport")]
[SwaggerOperation(OperationId = "PrintGravimetricSheetReport")]
[SwaggerResponse(200, "Ok", typeof(FileContentResult))]
[SwaggerResponse(400, "Bad Request", typeof(ErrorResponse))]
public async Task<IActionResult> PrintGravimetricSheetReport()
{
var vm  = new QuoteLineItemModel();
var documentContent = await _templateService.RenderTemplateAsync("GravSheet", vm);

var globalSettings = new GlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
Margins = new MarginSettings(){Top =10},
DocumentTitle = "GravSheet Report",
};
var objectSettings = new ObjectSettings
{
PagesCount = true,
HtmlContent = documentContent,
WebSettings = { DefaultEncoding = "utf-8" },
HeaderSettings = { FontName = "Arial", FontSize = 9, Right = "Page [page] of [toPage]", Line = true},
FooterSettings = { FontName = "Arial", FontSize = 9, Line = true, Center = "Report Footer"}
};
var pdf = new HtmlToPdfDocument
{
GlobalSettings = globalSettings,
Objects = {objectSettings}
};
var file = _converter.Convert(pdf);
return File(file, "application/pdf");
}

而角度中的分量法是:

printGravSheet(): void {
this.reportService.printGravimetricSheetReport().subscribe((blobResponse: Blob) => {
const fileUrl = window.URL.createObjectURL(blobResponse);
const showWindow = window.open(fileUrl);
if (!showWindow || showWindow.closed || typeof showWindow.closed === 'undefined') {
alert('Please disable your Pop-up blocker and try again');
}
});
};

最新更新