“不支持指定的方法” iTextSharp 错误

发布于 2024-11-14 08:01:31 字数 4045 浏览 6 评论 0原文

我正在使用 iTextSharp 生成 PDF。我在下面添加了一种测试方法,该方法可以制作一个包含一个段落的简单页面。它有效,生成了 PDF,但是,在将 PDF 发送到浏览器后的某个时间,我在事件日志中收到 NotSupportedException(或者如果我自己从 Application_Error 中捕获它们)。这是导致此错误的最简单的代码:

public FileStreamResult TestPdf()
{
  using (var ms = new MemoryStream())
  {
    using (var document = new Document())
    {
      PdfWriter.GetInstance(document, ms);
      document.Open();
      document.Add(new Paragraph("Hello World!"));
      document.Close();
    }
    Response.ContentType = "application/pdf";
    Response.AddHeader("content-disposition", "attachment;filename=test.pdf");
    Response.Buffer = true;
    Response.Clear();
    Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
    Response.OutputStream.Flush();
    Response.End();
  }
  return new FileStreamResult(Response.OutputStream, "application/pdf");
}

以及它抛出的错误(在请求完成后的某个时间)

Exception information: 
Exception type: NotSupportedException 
Exception message: Specified method is not supported.
at System.Web.HttpResponseStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase response)
at System.Web.Mvc.FileResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

关于如何解决此问题有什么想法吗?是图书馆有问题还是其他什么问题?

谢谢!

编辑:

为了解决这个问题,我可以通过控制器的 File 方法使用 FileContentResult,而不是返回 FileStreamResult。这是工作代码:

public ActionResult TestPdf()
{
  using (var ms = new MemoryStream())
  {
    using (var document = new Document())
    {
      PdfWriter.GetInstance(document, ms);

      document.Open();
      document.Add(new Paragraph("Hello World!"));
      document.Close();
    }
    Response.ContentType = "application/pdf";
    Response.AddHeader("content-disposition", "attachment;filename=test.pdf");
    Response.Buffer = true;
    Response.Clear();        
    return File(ms.ToArray(), "application/pdf");
  }
}

I'm using iTextSharp to generate PDFs. I've added a test method below that makes a simple page with one paragraph. It works, the PDF is generated, however, sometime after the PDF is sent to the browser I get a NotSupportedException in the Event log (or if I catch them myself from Application_Error). Here's the simplest code that causes this error:

public FileStreamResult TestPdf()
{
  using (var ms = new MemoryStream())
  {
    using (var document = new Document())
    {
      PdfWriter.GetInstance(document, ms);
      document.Open();
      document.Add(new Paragraph("Hello World!"));
      document.Close();
    }
    Response.ContentType = "application/pdf";
    Response.AddHeader("content-disposition", "attachment;filename=test.pdf");
    Response.Buffer = true;
    Response.Clear();
    Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
    Response.OutputStream.Flush();
    Response.End();
  }
  return new FileStreamResult(Response.OutputStream, "application/pdf");
}

And the error it throws (sometime after the request was completed)

Exception information: 
Exception type: NotSupportedException 
Exception message: Specified method is not supported.
at System.Web.HttpResponseStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase response)
at System.Web.Mvc.FileResult.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Any ideas on how I could fix this? Is there a problem with the library or something else?

Thanks!

Edit:

To solve this problem, rather than return FileStreamResult I was able to use FileContentResult instead via the Controller's File method. Here's the working code:

public ActionResult TestPdf()
{
  using (var ms = new MemoryStream())
  {
    using (var document = new Document())
    {
      PdfWriter.GetInstance(document, ms);

      document.Open();
      document.Add(new Paragraph("Hello World!"));
      document.Close();
    }
    Response.ContentType = "application/pdf";
    Response.AddHeader("content-disposition", "attachment;filename=test.pdf");
    Response.Buffer = true;
    Response.Clear();        
    return File(ms.ToArray(), "application/pdf");
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝戈者 2024-11-21 08:01:31

此行有一个错误:

Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);

使用 ToArray 而不是 GetBuffer。像这样:

var bytes = ms.ToArray();
Response.OutputStream.Write(bytes, 0, bytes.Length);

MemoryStream.GetBuffer 返回分配的字节,而不是填充的字节。

问题示例:

using (var memoryStream = new MemoryStream())
{
    memoryStream.WriteByte(1);
    var length = memoryStream.ToArray().Length; // returns 1
   var bufferLength = memoryStream.GetBuffer().Length; // returns 256
}

尽管添加了 1 个字节,GetBuffer 将返回 256 个字节。

There is an error is in this line:

Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);

Use ToArray instead of GetBuffer. Like this:

var bytes = ms.ToArray();
Response.OutputStream.Write(bytes, 0, bytes.Length);

MemoryStream.GetBuffer returns allocated bytes, not filled bytes.

Example of the issue:

using (var memoryStream = new MemoryStream())
{
    memoryStream.WriteByte(1);
    var length = memoryStream.ToArray().Length; // returns 1
   var bufferLength = memoryStream.GetBuffer().Length; // returns 256
}

Although one byte is added, GetBuffer will return 256 bytes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文