我正在使用带有asp web api的jquery.filedownload
插件来下载文件并显示来自服务器的错误消息。
我已经设置了插件,并在我的回复中添加了Cookie,如github所示:https://github.com/johnculviner/jquery.fileDownload
我的文件正在成功下载,但回调无效。
的js
var url = "/WebApi/PayrollBatches/GetBatchCsv?batchId=" + batchId;
$.fileDownload(url, {
successCallback: function (url) {
alert('success');
},
failCallback: function (responseHtml, url) {
alert('error');
}
});
return false;
//this is critical to stop the click event which will trigger a normal file download!
Asp Web Api
[HttpGet]
public async Task<HttpResponseMessage> GetBatchCsv(int batchId)
{
string csv;
try {
using (var Dbcontext = new RossEntities()) {
PayrollBatchExport dal = new PayrollBatchExport(Dbcontext);
csv = await dal.GetBatchCsv(batchId);
}
}
catch (Exception ex) {
HttpError myCustomError = new HttpError(ex.Message) { { "CustomErrorCode", 42 } };
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, myCustomError);
}
var cookie = new CookieHeaderValue("fileDownload", "true");
var cookiePath = new CookieHeaderValue("path", "/");
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(csv);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "Export.csv";
response.Headers.AddCookies(new CookieHeaderValue[] { cookie, cookiePath });
response.StatusCode = HttpStatusCode.OK;
return response;
}
修改
以下是我的浏览器控制台在服务器响应错误500时的样子:
答案 0 :(得分:1)
好的,在与Fiddler呆了一段时间之后,问题出在了一个cookie上。请注意jquery.fileDownload.js
:
function checkFileDownloadComplete() {
//has the cookie been written due to a file download occuring?
var cookieValue = settings.cookieValue;
if (typeof cookieValue == 'string') {
cookieValue = cookieValue.toLowerCase();
}
var lowerCaseCookie = settings.cookieName.toLowerCase() + "=" + cookieValue;
if (document.cookie.toLowerCase().indexOf(lowerCaseCookie) > -1) {
//execute specified callback
internalCallbacks.onSuccess(fileUrl);
...
仅当服务器返回cookie时,才会调用成功回调,如项目页面所示,但API控制器未正确返回此cookie。此代码适用于我,并且还描述了official docs
public class PayrollBatchesController : ApiController
{
[HttpGet]
public async Task<HttpResponseMessage> GetBatchCsv(int batchId)
{
string csv;
try
{
string path = System.Web.HttpContext.Current.Request.MapPath(@"~\Files\testfile.csv");
csv = File.ReadAllText(path);// await dal.GetBatchCsv(batchId);
}
catch (Exception ex)
{
HttpError myCustomError = new HttpError(ex.Message) { { "CustomErrorCode", 42 } };
HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, myCustomError);
errorResponse.Content = new StringContent("error: " + ex.ToString());
return errorResponse;
}
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
// Set Cookie
var cookie = new CookieHeaderValue("fileDownload", "true");
cookie.Expires = DateTimeOffset.Now.AddDays(1);
cookie.Domain = Request.RequestUri.Host;
cookie.Path = "/";
response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
// -------------
response.Content = new StringContent(csv);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "Export.csv";
response.StatusCode = HttpStatusCode.OK;
return response;
}
}
请注意,出于演示目的,我不是从DAL检索CSV数据,而是从上面的代码显示的测试文件中检索。另外,要完成这里,我附上客户端代码:
<body>
<div>
<button id="btn" type="button">get</button>
</div>
<script src="~/Scripts/fileDownload.js"></script>
<script>
$(document).ready(function () {
$('#btn').click(function () {
var url = "/api/PayrollBatches/GetBatchCsv?batchId=1";
$.fileDownload(url, {
successCallback: function (url) {
alert('success');
},
failCallback: function (responseHtml, url) {
alert('error');
}
});
return false;
});
});
</script>
</body>
编辑:失败回调