如何使用 ServiceStack 和 Angular 下载动态生成的 XML 文件?
How to download a dynamically generated XML file with ServiceStack and Angular?
以下代码在理论上可以工作,但缺少错误处理。我遇到的问题是,当使用服务堆栈创建的 url 打开新的 window 时,它开始下载 XML 文件。但是现在当服务器端发生错误时,您在这个只有堆栈跟踪的新页面上。
使用服务堆栈和 Angular 下载动态二进制文件(未存储在磁盘上)的正确方法是什么?
Angular 与 ServiceStack:
downloadExportXML(){
const request = new GetRatingsExportRequest(this.request);
const url = this.jsonServiceClient.createUrlFromDto("GET", request)
window.open(url);
}
WebAPI (C#) 收集 XML 文件。
public HttpResult Get(GetRatingsExportRequest request)
{
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xmlContent));
var result = new HttpResult(ms.ToArray());
var disposition = $"attachment;filename=myfilename;";
result.Headers.Add(HttpHeaders.ContentDisposition, disposition);
return result;
}
如果您 return 使用 Content-Disposition: attachment
HTTP Header 的内容,浏览器会将其视为单独的文件下载。
如果您不希望 return 它作为正常 XML 响应。但是你 returning 它的方式是相当低效的,即调用 ToArray()
违背了使用 Stream 的目的,因为你已经强制将 Stream 的全部内容加载到内存中,而你应该只是return 流,以便它作为流异步写入 HTTP 响应,例如:
return new HttpResult(ms, MimeTypes.Xml);
但是,如果您已经将 XML 作为字符串获得,则您也不需要 MemoryStream
包装器的开销,只需 return XML 字符串 as-is,例如:
return new HttpResult(xmlContent, MimeTypes.Xml);
我无法让它工作。所以我创建了这个解决方法:使用 ServiceStack 方法 jsonServiceClient.createUrlFromDto()
生成 URL 以下载 XML,而不是通过 Angular HTTPClient 下载文件。
downloadExportXML(){
const request = new GetRatingsExportRequest(this.request);
const url = this.jsonServiceClient.createUrlFromDto("GET", request)
this.httpClient.get(url, {observe: 'response', responseType: 'arraybuffer'})
.subscribe((response) => {
var contentDisposition = response.headers.get('content-disposition');
this.downloadFile(response.body)
},
error => this.handleError()
);
}
private downloadFile(blobData: ArrayBuffer)
{
let file = new Blob([blobData], { type: 'application/binary' });
let fileURL = URL.createObjectURL(file);
let fileLink = document.createElement('a');
fileLink.href = fileURL;
fileLink.download = "MYFILENAME.pdf";
fileLink.click();
}
以下代码在理论上可以工作,但缺少错误处理。我遇到的问题是,当使用服务堆栈创建的 url 打开新的 window 时,它开始下载 XML 文件。但是现在当服务器端发生错误时,您在这个只有堆栈跟踪的新页面上。
使用服务堆栈和 Angular 下载动态二进制文件(未存储在磁盘上)的正确方法是什么?
Angular 与 ServiceStack:
downloadExportXML(){
const request = new GetRatingsExportRequest(this.request);
const url = this.jsonServiceClient.createUrlFromDto("GET", request)
window.open(url);
}
WebAPI (C#) 收集 XML 文件。
public HttpResult Get(GetRatingsExportRequest request)
{
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xmlContent));
var result = new HttpResult(ms.ToArray());
var disposition = $"attachment;filename=myfilename;";
result.Headers.Add(HttpHeaders.ContentDisposition, disposition);
return result;
}
如果您 return 使用 Content-Disposition: attachment
HTTP Header 的内容,浏览器会将其视为单独的文件下载。
如果您不希望 return 它作为正常 XML 响应。但是你 returning 它的方式是相当低效的,即调用 ToArray()
违背了使用 Stream 的目的,因为你已经强制将 Stream 的全部内容加载到内存中,而你应该只是return 流,以便它作为流异步写入 HTTP 响应,例如:
return new HttpResult(ms, MimeTypes.Xml);
但是,如果您已经将 XML 作为字符串获得,则您也不需要 MemoryStream
包装器的开销,只需 return XML 字符串 as-is,例如:
return new HttpResult(xmlContent, MimeTypes.Xml);
我无法让它工作。所以我创建了这个解决方法:使用 ServiceStack 方法 jsonServiceClient.createUrlFromDto()
生成 URL 以下载 XML,而不是通过 Angular HTTPClient 下载文件。
downloadExportXML(){
const request = new GetRatingsExportRequest(this.request);
const url = this.jsonServiceClient.createUrlFromDto("GET", request)
this.httpClient.get(url, {observe: 'response', responseType: 'arraybuffer'})
.subscribe((response) => {
var contentDisposition = response.headers.get('content-disposition');
this.downloadFile(response.body)
},
error => this.handleError()
);
}
private downloadFile(blobData: ArrayBuffer)
{
let file = new Blob([blobData], { type: 'application/binary' });
let fileURL = URL.createObjectURL(file);
let fileLink = document.createElement('a');
fileLink.href = fileURL;
fileLink.download = "MYFILENAME.pdf";
fileLink.click();
}