我试图从Microsoft Web API 2控制器下载csv文件。这是我到目前为止所拥有的: -
Web API: -
[Route("extractContent/{extractId}")]
public async Task<IHttpActionResult> GetExtractContent(int extractId)
{
_logger.Info($"Getting extract file content for extract with id: {extractId}...");
try
{
IEnumerable<ExtractDto> extracts = await _extractService.GetExtractsAsync(new ExtractSearchRequest { ExtractId = extractId });
ExtractDto extract = extracts?.FirstOrDefault();
if (extract != null)
{
string path = extract.FilePath;
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
using (result.Content = new StreamContent(stream))
{
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = Path.GetFileName(path)
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return Ok(result);
}
}
throw new InvalidOperationException($"Could not find extract with id: {extractId}");
}
catch (Exception e)
{
_logger.ErrorException($"An error occured trying to get extract content for extract with id: {extractId}", e);
return InternalServerError(e);
}
}
Angular 2下载服务: -
@Injectable()
export class DownloadService {
private baseAddress: string;
private headers: Headers;
private options: RequestOptions;
constructor(private http: Http, private config: Config, private errorService: ErrorService) {
this.baseAddress = config.cache.get('portfolioUploadApiUrl');
this.headers = new Headers({ 'Content-Type': 'application/json' });
this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType: ResponseContentType.Blob});
}
getExtractContent(extractId: number): Observable<Blob> {
return this.http.get(this.baseAddress + 'extractContent/' + extractId, this.options)
.map((response: Response) =>
{
return new Blob([response.blob()], {type: 'application/csv'});
}
)
.catch(this.errorService.handleError);
}
}
Angular 2客户端代码: -
onDownload(): void {
if (this.extract && this.extract.FilePath) {
this.downloadService.getExtractContent(this.extractId).subscribe(blob => {
var date = new Date();
var day = date.getDay();
var month = date.getMonth();
var year = date.getFullYear();
var seconds = date.getSeconds();
var minutes = date.getMinutes();
var hours = date.getHours();
var formattedDate = day + '' + (month + 1) + '' + year + '' + hours + '' + minutes + '' + seconds;
var fileName = "Extract" + this.extractId + "-" + formattedDate + ".csv";
FileSaver.saveAs(blob, fileName)
})
}
}
但是,当我运行下载时,我会下载一个csv文件,其中包含以下内容: -
{&#34;版本&#34;:{&#34; _Major&#34;:1 _Minor:1 _Build:-1 _Revision:-1}内容:{&#34; Headers&#34;:[{ &#34;键&#34;:&#34;内容处置&#34;值:[&#34;附件; filename = \&#34; RPModel_Portfolio_ISY - 20170925.csv \&#34;&#34;]} {&#34; Key&#34;:&#34; Content-Type&#34;值:[&#34; application / octet-stream&#34;]}]} StatusCode:200 ReasonPhrase:&#34; OK&#34;标题:[] RequestMessage:null IsSuccessStatusCode:true}
有人可以帮忙吗?
由于
答案 0 :(得分:0)
从WebAPI下载XML文件时遇到同样的问题。
RequestOptions存在差异,当有二进制文件(.PDF,.ZIP,...)时,您可以调用:
this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType: ResponseContentType.Blob});
但是,当文件是文本文件(.txt,.csv,...)时,你必须调用API来询问文本文件,所以:
this.options = new RequestOptions({ headers: this.headers, withCredentials: true, responseType: ResponseContentType.Text});
在我的情况下,我创建了一个从API接收响应并创建通信文件的过程。
saveFile(data, fileName: string, extentionFile: string) {
var mediaType = data.headers.get("Content-Type");
var file;
if (extentionFile == "csv") {
file = new Blob([data._body], { type: mediaType })
} else {
file = new Blob([data.blob()], { type: mediaType })
}
FileSaver.saveAs(file, fileName);
}
当Response返回文本时,您将从Response的主体创建一个blob。如果返回二进制文件,您可以调用&#34; .blob()&#34;。
我希望它对你有所帮助。
答案 1 :(得分:0)
我无法弄清楚如何解决这个问题所以我只是从我的Web API操作中提供了我的csv数据的json表示,然后只使用Angular2Csv Angular 2库将此json对象转换为CSV文件
出于某种原因,使用ResponseMessage(result)而不是其他Web API包装器(例如Ok(result))意味着实际请求会忽略CORS。 OPTIONS(飞行前)请求似乎有效,但GET在使用ResponseMessage(结果)时没有,但是在使用Ok(结果)时它确实如此,所以我只能假设Ok(结果)正在做一些事情来使用Web API 2中提供的Cors功能