我使用带有.NET webApi(.NET 4.5框架)的角度为6的Web App。
我正在做的是收集一些用户输入,并将请求发送到webapi。 Webapi使用来自数据库的一些数据生成一个excel文件(xlsx或xlsm)。 现在,我需要在用户计算机上下载此文件。 我已在服务器上验证,生成的文件正确并在服务器上的temp目录中创建。 但是它正在作为损坏的文件下载到用户计算机上,而Excel无法打开它。
任何想法我该如何解决。
WebApi代码
[System.Web.Http.HttpPut]
public ActionResult Put(Parameters inputs)
{
var path = GenerateFile(inputs);
string extension = new FileInfo(path).Extension;
switch (extension)
{
case ".xls":
return new FilePathResult(path, "application/msexcel");
case ".xlsx":
return new FilePathResult(path, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
case ".xlsm":
return new FilePathResult(path, "application/vnd.ms-excel.sheet.macroEnabled.12");
}
}
角度代码:
GenerateReprot() {
this.http.put(this.webApiURL, this.Input, 'arraybuffer')
.subscribe(
result => {
this.downLoadFile(result, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
alert('file downloaded successfully. ');
},
error => {
alert('error with downloading file.');
}
);
}
downLoadFile(data: any, type: string) {
var blob = new Blob([data], { type: type });
var url = window.URL.createObjectURL(blob);
var pwa = window.open(url);
if (!pwa || pwa.closed || typeof pwa.closed == 'undefined') {
alert('Please disable your Pop-up blocker and try again.');
}
}
答案 0 :(得分:1)
您的标记显示asp.net-web-api,而您显示System.Web.Http
名称空间,但是该框架没有使用ActionResult
。所以看起来您正在混合MVC和Web API之间的框架
很可能您返回了错误的模型类型,并将其序列化为JSON,这就是文件读取器将其视为损坏的原因。
以下内容假设它是在ApiController
[HttpPut]
public IHttpActionResult Put(Parameters inputs) {
var path = GenerateFile(inputs);
var file = new FileInfo(path);
string contentType = null;
switch (file.Extension) {
case ".xls":
contentType = "application/msexcel";
case ".xlsx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
case ".xlsm":
contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
}
var stream = file.OpenRead();
var content = new StreamContent(stream);
content.Headers.ContentLength = stream.Length;
content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
FileName = file.Name
};
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content;
return ResponseMessage(response);
}
答案 1 :(得分:0)
在您的HTTP put请求中尝试responseType: "blob"
。
this.http.put(this.webApiURL, this.Input, { responseType: "blob" })
.subscribe(
...
);
答案 2 :(得分:0)
Angular在下载文件时遇到一些奇怪的问题。仅发出put请求,我无法下载文件。我不得不将请求分为两部分 1.提出文件准备请求 2.收到文件下载请求
仅发出put请求,它总是下载1KB损坏的文件。 在Angular中,您也不需要使用任何arraybuffer或blob。它们还会引起一些奇怪的问题。
这是代码(webapi)
[HttpPut]
public string Put(Parameters inputs)
{
var file = GenerateFile(inputs);
return Path.GetFileNameWithoutExtension(file);
}
[HttpGet]
public HttpResponseMessage Get(string id) //id is file name returned from above put request
{
var result = Request.CreateResponse(HttpStatusCode.OK);
var fullPath = Path.Combine(Path.GetTempPath(), id + ".xlsx");
if (!File.Exists(fullPath))
{
fullPath = Path.Combine(Path.GetTempPath(), id + ".xlsm");
if (!File.Exists(fullPath))
throw new FileNotFoundException(id);
}
var stream = new MemoryStream(File.ReadAllBytes(fullPath));
result.Content = new StreamContent(stream);
switch (Path.GetExtension(fullPath))
{
case ".xls":
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/msexcel");
break;
case ".xlsx":
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
break;
case ".xlsm":
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel.sheet.macroEnabled.12");
break;
}
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = Path.GetFileName(fullPath)
};
return result;
}
角度代码:
GenerateReprot() {
this.http.put(this.webApiURL, this.Input)
.subscribe(
result => {
var url = this.webApiURL + result.json();
window.open(url)
alert('file downloaded successfully: ');
}),
error => {
alert('error while downloading file');
};
}