"Specified Method Not Supported" Error with iTextSharp

I use iTextSharp to create PDF files. I have added a testing method below which makes a simple page with one paragraph. It works, the PDF is created, however, sometime after sending the PDF message to the browser, I get a NotSupportedException in the event log (or if I catch them myself from Application_Error). Here is 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 (some time after the request is 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 can fix this? Is there a problem with the library or something else?

Thanks!

Edit:

To solve this problem, instead of returning a FileStreamResult, I was able to use FileContentResult instead through the Controller 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"); } } 
+4
source share
1 answer

There is an error 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 problem:

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

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

+1
source

All Articles