C# MVC 5控制器返回PDF文件不';行不通
我正在尝试为我的项目创建一个打印PDF文件 这是我的密码C# MVC 5控制器返回PDF文件不';行不通,c#,asp.net-mvc,pdf,C#,Asp.net Mvc,Pdf,我正在尝试为我的项目创建一个打印PDF文件 这是我的密码 [HttpPost] [ValidateAntiForgeryToken] public ActionResult PrintPdf(SubmitReport model) { if (model == null) { throw new ArgumentNullException(nameof(SubmitReport)); }
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrintPdf(SubmitReport model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(SubmitReport));
}
var pdfModel = new PdfViewModel {HeaderImgUrl = AppDomain.CurrentDomain.BaseDirectory + @"Content\logo.jpg"};
var pdfStream = new MemoryStream(PdfGenerator.PayrollConfirmPdf(pdfModel).ToArray());
// TODO: what is the name of the pdf file?
var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");
return File(pdfStream, "application/pdf", filename);
}
看起来一切正常,但函数返回后,什么也没有发生。我希望在本地机器上打开/下载PDF文件。但是,没有弹出窗口显示(好像什么都没有发生)
有什么想法吗
提前感谢。这句话似乎搞乱了:
var pdfStream = new MemoryStream(PdfGenerator.PayrollConfirmPdf(pdfModel).ToArray());
这将从字节数组创建MemoryStream
的实例,它可能从流的末尾而不是开始读取FileResult
您可以使用以下两种可能的解决方案之一:
1) 将MemoryStream
从PayrollConfirmPdf
方法转换为字节数组,并将PDF作为FileContentResult
返回:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrintPdf(SubmitReport model)
{
// other stuff
byte[] pdfStream;
using (var stream = new MemoryStream())
{
// fill stream content from other source
stream = PdfGenerator.PayrollConfirmPdf(pdfModel);
pdfStream = stream.ToArray();
}
// TODO: what is the name of the pdf file?
var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");
// FileContentResult
return File(pdfStream, "application/pdf", filename);
}
2) 返回FileStreamResult
,将Seek
方法设置为流的开头:
using (var stream = new MemoryStream())
{
// fill stream content from other source
// make sure that PayrollConfirmPdf return MemoryStream here!
stream = PdfGenerator.PayrollConfirmPdf(pdfModel);
// add this line when using memory stream
// alternative 1: stream.Seek(0, 0);
stream.Seek(0, SeekOrigin.Begin);
var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");
// FileStreamResult
return File(stream, "application/pdf", filename);
}
请注意,您可以使用stream.Position=0
如果stream.Seek方法不起作用,则重置流位置
旁注:
由于MemoryStream
实现了IDisposable
,因此应该使用using
语句立即处理流
类似问题:
(如果使用AJAX POST下载文件)这一行似乎搞乱了:
var pdfStream = new MemoryStream(PdfGenerator.PayrollConfirmPdf(pdfModel).ToArray());
这将从字节数组创建MemoryStream
的实例,它可能从流的末尾而不是开始读取FileResult
您可以使用以下两种可能的解决方案之一:
1) 将MemoryStream
从PayrollConfirmPdf
方法转换为字节数组,并将PDF作为FileContentResult
返回:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrintPdf(SubmitReport model)
{
// other stuff
byte[] pdfStream;
using (var stream = new MemoryStream())
{
// fill stream content from other source
stream = PdfGenerator.PayrollConfirmPdf(pdfModel);
pdfStream = stream.ToArray();
}
// TODO: what is the name of the pdf file?
var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");
// FileContentResult
return File(pdfStream, "application/pdf", filename);
}
2) 返回FileStreamResult
,将Seek
方法设置为流的开头:
using (var stream = new MemoryStream())
{
// fill stream content from other source
// make sure that PayrollConfirmPdf return MemoryStream here!
stream = PdfGenerator.PayrollConfirmPdf(pdfModel);
// add this line when using memory stream
// alternative 1: stream.Seek(0, 0);
stream.Seek(0, SeekOrigin.Begin);
var filename = string.Concat("PayrollConfirmation", DateTime.Now.ToString("yyyyMMddHHmmss"), ".pdf");
// FileStreamResult
return File(stream, "application/pdf", filename);
}
请注意,您可以使用stream.Position=0
如果stream.Seek方法不起作用,则重置流位置
旁注:
由于MemoryStream
实现了IDisposable
,因此应该使用using
语句立即处理流
类似问题:
(如果使用AJAX POST下载文件)检查pdfStream
的输出,是否返回包含PDF文件的字节数组?还可以尝试以下操作:var pdfStream=newmemorystream(PdfGenerator.payrollconfirmpd(pdfModel)).ToArray()
@TetsuyaYamamoto是的,我强制它是字节数组:byte[]pdfStream;var stream=newmemoryStream();使用(stream){stream=PdfGenerator.PayrollConfirmPdf(pdfModel);pdfStream=stream.ToArray();}
问题仍然存在。检查pdfStream
的输出,是否返回包含PDF文件的字节数组?还可以尝试以下操作:var pdfStream=newmemorystream(PdfGenerator.payrollconfirmpd(pdfModel)).ToArray()
@TetsuyaYamamoto是的,我强制它是字节数组:byte[]pdfStream;var stream=newmemoryStream();使用(stream){stream=PdfGenerator.PayrollConfirmPdf(pdfModel);pdfStream=stream.ToArray();}
问题仍然存在。感谢您的回答,我尝试使用IDisposable。我收到一个错误:“严重性代码描述项目文件行抑制状态错误CS1656无法分配给'stream',因为它是一个'using variable'”
,再次感谢您的详细回答。我也试过你的解决办法。我可以验证蒸汽是否含有物质。但是,它的行为仍然相同。同样的问题还在那里。我挖了一点。主要问题在前端。因为我使用的是AJAX post,并且成功生成了pdf文件。我只需要让前端抓取文件。如果您使用的是AJAX POST,那么您应该使用success
块来确保收到响应,并使用window.location.href
重定向到GET action方法,该方法返回FileResult
(AJAX主要用于在停留在同一页面时发送请求).谢谢你的回答,我试过使用IDisposable。我收到一个错误:“严重性代码描述项目文件行抑制状态错误CS1656无法分配给'stream',因为它是一个'using variable'”
,再次感谢您的详细回答。我也试过你的解决办法。我可以验证蒸汽是否含有物质。但是,它的行为仍然相同。同样的问题还在那里。我挖了一点。主要问题在前端。因为我使用的是AJAX post,并且成功生成了pdf文件。我只需要让前端抓取文件。如果您使用的是AJAX POST,那么您应该使用success
块来确保收到响应,并使用window.location.href
重定向到GET action方法,该方法返回FileResult
(AJAX主要用于在停留在同一页面时发送请求)。