C# 如何在MVC中返回动作结果中的PDF

C# 如何在MVC中返回动作结果中的PDF,c#,ajax,asp.net-mvc,pdf,iframe,C#,Ajax,Asp.net Mvc,Pdf,Iframe,我在想这个问题时有点困难。我有一个ajax调用,它应该呈现一个加载PDF的iframe。PDF是使用托管在另一个环境中的ApacheFop生成的。到目前为止,我得到的是: 在控制器操作(iFrame的src元素指向的地方)中,代码段是: var targetStream = new MemoryStream(); using (var response = FOPrequest.GetResponse()) // response from FOP {

我在想这个问题时有点困难。我有一个ajax调用,它应该呈现一个加载PDF的iframe。PDF是使用托管在另一个环境中的ApacheFop生成的。到目前为止,我得到的是:

在控制器操作(iFrame的src元素指向的地方)中,代码段是:

var targetStream = new MemoryStream();    
using (var response = FOPrequest.GetResponse()) // response from FOP
                {
                    using (var stream = response.GetResponseStream())
                    {
                        stream.CopyTo(targetStream);

                    }
                }
 return new FileStreamResult(targetStream, "application/pdf");
然而,这并不像预期的那样有效。流按预期填充,但PDF不会在iFrame中呈现。 我得到的Http响应代码是200(OK)

如果有任何帮助,我将不胜感激。

您使用MVC返回ActionResult 例如:

return File(fileArray, contentType, fileName)

另一个堆栈

您可以使用返回类型作为
FileResult
,如下所示:

public FileResult getFile(string CsvName)
{
   //Add businees logic here
   byte[] fileBytes = System.IO.File.ReadAllBytes(System.Web.Hosting.HostingEnvironment.MapPath("~/Content/Uploads/records.csv"));
   string fileName = CsvName;
   return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
可能不是精确的解决方案,您可以操纵并开发自己的解决方案


希望这有帮助。

通过nuget安装MvcPdfActionResult

PM> Install-Package MvcPdfActionResult
只需使用返回类型,控制器将输出PDF文档而不是HTML。这将使用iTextXmlWorker库将HTML转换为PDF

  ...
  return PdfActionResult(model);
}
从asp.net 5 MVC项目中的razor视图生成pdf文档。

对于文件流,结果您的targetStream需要保持打开状态。 “使用”部分关闭您的响应流,看起来您的targetStream也关闭了,然后


当我使用未关闭的MemoryStream时,您的代码可以工作!感谢Natan Cooper的评论和链接,我得到了它。

尽管标准操作结果FileContentResult或FileStreamResult可用于下载文件,但为了可重用性,创建自定义操作结果可能是最好的解决方案。创建自定义操作结果PDFResult

PDFResult类继承抽象ActionResult类并重写ExecuteSult方法

public class PDFResult : ActionResult
{
    private readonly byte[] fileContents;
    private string fileName;

    public PDFResult(byte[] contents, string filename)
    {
        this.fileContents = contents;
        this.fileName = filename;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.Clear();
        response.ContentType = "application/pdf";
        response.AddHeader("content-disposition", string.Format(@"attachment;filename=""{0}""", fileName));
        response.BinaryWrite(fileContents);
    }
}
在控制器中,使用自定义PDFResult操作结果,如下所示

[HttpGet]
public async Task<PDFResult> ExportToPDF()
{
    var model = new Models.MyDataModel();
    byte[] fileContents = await model.GetFileContents();
    string filename = "myfile.pdf";
    return new PDFResult(fileContents, filename);
}
[HttpGet]
公共异步任务ExportToPDF()
{
var model=new Models.MyDataModel();
byte[]fileContents=wait model.GetFileContents();
字符串filename=“myfile.pdf”;
返回新的PDFResult(文件内容、文件名);
}
因为我们使用HttpGet下载文件,所以创建一个没有模型和空布局的空视图

关于下载动态创建的文件的自定义操作结果的博客文章:


。我不完全确定这一点,但如果明确表示希望在iframe中渲染,会发生什么情况<代码>Response.AppendHeader(“内容处置”、“内联;pdfname.pdf”)然而,我认为你的问题可能在于你的razer代码,你可能想发布它。正如Nathan所说,最好也关注razer代码,以便找到解决方案。可能是重复的