Asp.net mvc .Net Web API PDF下载不起作用
我正在开发一个基于.NETMVC5项目的Durandal应用程序。我有一个WebAPI2控制器,它通过获取一些数据并使用将其合并到现有的PDF模板中来生成PDF。这很好,我可以将新的PDF保存到磁盘我的问题是,我想将新的PDF流式传输到浏览器,以便用户可以下载它-但它不起作用。我尝试了许多解决方案,但都没有效果 理想情况下,我甚至不希望将生成的PDF保存到磁盘,因为它似乎没有必要。这是我尝试的第一种方法——将所有内容都保存在内存中,将新的PDF写入字节数组并将其发送回浏览器。在尝试了所有我能找到的解决方案后,我决定将新文件保存到磁盘,并尝试将新文件流式传输到浏览器。我想那将有助于缩小问题的范围 下面是api请求之后的响应头 但在浏览器(最新版本的Chrome、Firefox和IE)中什么也没有发生。 以下是我的控制器和下载方法: 我在客户端使用Durandal/Knockout/Breeze,在服务器端使用EF6、Breeze和webapi2。我已确保包含PDF的文件夹具有完整的安全权限,并将Asp.net mvc .Net Web API PDF下载不起作用,asp.net-mvc,pdf,asp.net-web-api,download,durandal,Asp.net Mvc,Pdf,Asp.net Web Api,Download,Durandal,我正在开发一个基于.NETMVC5项目的Durandal应用程序。我有一个WebAPI2控制器,它通过获取一些数据并使用将其合并到现有的PDF模板中来生成PDF。这很好,我可以将新的PDF保存到磁盘我的问题是,我想将新的PDF流式传输到浏览器,以便用户可以下载它-但它不起作用。我尝试了许多解决方案,但都没有效果 理想情况下,我甚至不希望将生成的PDF保存到磁盘,因为它似乎没有必要。这是我尝试的第一种方法——将所有内容都保存在内存中,将新的PDF写入字节数组并将其发送回浏览器。在尝试了所有我能找到
runAllManagedModulesForAllRequests=“true”
属性放在我的web.config中的modules
元素上
有什么想法吗?你应该可以用字节数组来实现这一点,没问题。我觉得你的服务器代码很好 我猜问题在于不能使用XHR/ajax类型的请求在浏览器中触发文件下载工作流。您只需在HTML中呈现一个链接,href指向您的API端点。您还需要将服务器操作方法更改为GET
当用户单击链接时,它将执行GET,结果响应将触发文件下载对话框。如果您将媒体类型设置为
application/pdf
,那么像Chrome这样的浏览器将直接呈现它。下面就是一个例子
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 169729
Content-Type: application/octet-stream
Expires: -1
Server: Microsoft-IIS/8.0
Content-Disposition: attachment; filename=myEticket.pdf
[RoutePrefix("api/tickets")]
[AllowAnonymous] // for debugging only
public class EticketsController : ApiController
{
[HttpGet,HttpPost, Route("download")]
public HttpResponseMessage DownloadPdf([FromBody] Eticket model)
{
const string templateName = "eTicketFinal.pdf";
const string outputname = "eTicket_new.pdf";
var templatePdfPath = Path.Combine(HttpContext.Current.Server.MapPath("~/eTickets/"), templateName);
var outputpath = Path.Combine(HttpContext.Current.Server.MapPath("~/eTickets/"), outputname);
var eticket = _unitOfWork.EticketRepository.GetById(model.EticketId);
var pdfticket = Mapper.Map<EticketPdf>(eticket);
using (var fdfApp = new FDFApp_Class())
{
using (var fdfDoc = fdfApp.FDFCreate())
{
var properties = pdfticket.GetType().GetProperties();
foreach (var prop in properties)
{
var name = prop.Name;
var propvalue = prop.GetValue(pdfticket, null);
var value = propvalue == null ? string.Empty : propvalue.ToString();
fdfDoc.FDFSetValue(name, value);
}
// this is working and creating the file on disk
fdfDoc.PDFMergeFDF2File(outputpath, templatePdfPath);
fdfDoc.FDFClose();
}
}
var stream = new FileStream(outputpath, FileMode.Open);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(stream)
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
//use attachment to force download
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "myEticket.pdf"
};
return result;
}
}
$.ajax({
type: 'POST',
url: '/api/tickets/download',
data: postdata,
datatype: 'json',
contentType: 'application/json; charset=utf-8'
});