MVC. Itextsharp write pdf to response - model-view-controller

I am generating pdf using itexsharp.
I am creating MemoryStream, then when i am trying t write MemoryStream bytes in to response but no luck. When i am executing this code in my controller the pdf not coming in response. Memory stream is populaitng correctly i can see this in debugger, but for some reason this number of butes not coming in response.
Here is my code:
HttpContext.Current.Response.ContentType = "application/pdf";
...
using (Stream inputPdfStream = new FileStream(pdfFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new MemoryStream())
{
PdfReader reader = new PdfReader(inputPdfStream);
PdfStamper stamper = new PdfStamper(reader, outputPdfStream);
....
//try one
outputPdfStream.WriteTo(HttpContext.Current.Response.OutputStream); // NOT POPULATING Response
//try two
HttpContext.Current.Response.BinaryWrite(outputPdfStream.ToArray()); // NOT POPULATING Response Too
HttpContext.Current.Response.End();
}
May be some one have any ideas?

Could you not use
Response.ContentType = "application/pdf"
Response.AddHeader("Content-Type", "application/pdf")
Response.WriteFile(pdfFilePath)
Response.End()

You should use the FileContentResult Controller.File(byte[] content, string contentType) method:
public ActionResult GeneratePDF()
{
var outputStream = new MemoryStream(); // This will hold the pdf you want to send in the response
/*
* ... code here to create the pdf in the outputStrem
*/
return File(outputStream.ToArray(), "application/pdf");
}
Source: Building PDFs in Asp.Net MVC 2.

Probably the memorystream is still set at the position after the last written byte. It will write all bytes from the current position (which is none). If you do a outputPdfStream.Seek(0) it will set the position back to the first byte, and will write the contents of the whole stream to the response output.
Anyway, like Dean says, you should just use the Reponse.WriteFile method.

Related

Unable to download PDF file, fetched from Sql Database.Bytes value has been fetched, Function doesn't through any error, But PDF is not downloaded

I am unable to download a PDF file, fetched from Sql Database. Bytes value has been fetched, Function doesn't throw any error, but the PDF is not downloaded.
Code:
public ActionResult PrintPDF(string projectSelection)
{
byte[] extract = (byte[])_selectionManager.FindPdf();
MemoryStream pdfStream = new MemoryStream();
pdfStream.Write(extract, 0, extract.Length);
pdfStream.Position = 0;
HttpContext.Response.AddHeader("content-disposition",
"attachment; filename=form.pdf");
return new FileStreamResult(pdfStream, "application/pdf");
}
Since you already have the file content as bytes, why converting it to stream ?
Please check if this works
byte[] extract = (byte[])_selectionManager.FindPdf();
return File(
extract, System.Net.Mime.MediaTypeNames.Application.Pdf, "form.pdf");

What is the alternative for HttpContext.Response.OutputStream to use in WebAPI's HttpResponseMessage

I'm writing a WebAPI for handling PDF documents. It was written in a ashx page earlier implementing IHttpHandler and getting the context using HttpContext. I'm now writing it using WebAPI. In WebAPI we have HttpResponseMessage. For HttpContext.Response.BinaryWrite we have new ByteArrayContent in HttpResponseMessage. But what is the alternative for HttpContext.Response.OutputStream in WebAPI? I need to have the alternative of OutputStram in WebAPI because im passing this OutputStream as a parameter to another dll.
Code in ashx:
SomeReport.PdfReport rpt = new SomeReport.PdfReport(docID);
rpt.CreateReport(context.Response.OutputStream);
Actually you can use any stream for example MemoryStream but result should be wrapped into StreamContent.
public HttpResponseMessage Get()
{
var response = Request.CreateResponse();
var outputStream = new MemoryStream();
//write data to output stream
//or passing it to somewhere
outputStream.WriteByte(83);
outputStream.Position = 0;
response.Content = new StreamContent(outputStream);
return response;
}
If you need direct writing to output stream, please consider using PushStreamContent. Example

Getting the zero byte in the PutFile method in request body

We are getting the zero byte in the PutFile method in request body, but we can do the online editing of document and it is reflecting in other browsers as well (if we are editing the file in two browsers at same time ).
We are using ASP.Net Core and we are reading the request body like -
var bytes = new byte[context.Request.Body.Length];
context.Request.Body.Read(bytes, 0, bytes.Length);
Can anyone please help us on this one?
I solved this problem by using following code -
byte[] bytes;
context.Request.Body.Seek(0, SeekOrigin.Begin);
using (MemoryStream memoryStream = new MemoryStream())
{
context.Request.Body.CopyTo(memoryStream);
bytes = memoryStream.ToArray();
}

How do I read from a GZIPInputStream in Xamarin.android?

I have a an Array of bytes byteArray which contains data compressed with Gzip. I want to read the whole array and decode the data using the appropriate encoding ("ISO-8859-15").
GZIPInputStream gzipInputStream = new GZIPInputStream(new MemoryStream(personalDataArray));
InputStreamReader inputStream = new InputStreamReader(gzipInputStream);
However I get a compiler error when trying to read the gzip input stream with an Input stream reader, it says cannot convert from Java.Util.Zip.GZipInputStream to System.IO.Stream. This issue does not occur in Java though. How do I get around this? How do I specify the encoding to be used too? Thanks.
You can use this method to decompress GZip, use GZipStream
Here you have Xamarin doc. about System.IO.Compression.GZipStream Class
static byte[] Decompress(byte[] data)
{
using (var compressedStream = new MemoryStream(data))
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}
}
And you can read it using Encoding.UTF8.GetString(),
var msg = Encoding.UTF8.GetString(Decompress(personalDataArray));
Also You have to convert UTF-8 to ISO-8859-15 (Latin9), this sample is for ISO-8859-1 (Latin1), but try with ISO-8859-15.
var strISO88591= Encoding.GetEncoding("ISO-8859-1")
.GetString(Encoding.Conver‌​t(Encoding.UTF8,Encoding.GetEncoding("ISO-8859-1"), Encoding.UTF8.GetBytes(msg)));

Web API - Setting Response.Content with byte[] / MemoryStream Contents not working properly

My requirement is to use Web API to send across the network, a zip file (consisting a bunch of files in turn) which should not be written anywhere locally (not written anywhere on the server/client disk). For zipping, I am using DotNetZip - Ionic.Zip.dll
Code at Server:
public async Task<IHttpActionResult> GenerateZip(Dictionary<string, StringBuilder> fileList)
{
// fileList is actually a dictionary of “FileName”,”FileContent”
byte[] data;
using (ZipFile zip = new ZipFile())
{
foreach (var item in filelist.ToArray())
{
zip.AddEntry(item.Key, item.Value.ToString());
}
using (MemoryStream ms = new MemoryStream())
{
zip.Save(ms);
data = ms.ToArray();
}
}
var result = new HttpResponseMessage(HttpStatusCode.OK);
MemoryStream streams = new MemoryStream(data);
//, 0, data.Length-1, true, false);
streams.Position = 0;
//Encoding UTFEncode = new UTF8Encoding();
//string res = UTFEncode.GetString(data);
//result.Content = new StringContent(res, Encoding.UTF8, "application/zip");
<result.Content = new StreamContent(streams);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
//result.Content.Headers.ContentLength = data.Length;
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = "test.zip";
return this.Ok(result);
}
The issue I am facing is that after the zip file downloaded at client end when modified as a test.bin has its stream contents (byte[] data in this example’s contents) missing. (I am getting back a test.zip file. When I change the file locally from test.zip to test.bin, I am seeing that the File’s contents as shown below. It does not contain the Response.Content values. P.S. I have also tried the MIME type “application/octet-stream” as well. No luck!)
Test.zip aka test.bin’s contents:
{"version":{"major":1,"minor":1,"build":-1,"revision":-1,"majorRevision":-1,"minorRevision":-1},
"content":{"headers":[{"key":"Content-Type","value":["application/zip"]},
{"key":"Content-Disposition","value":["attachment; filename=test.zip"]}]},
"statusCode":200,"reasonPhrase":"OK","headers":[],"isSuccessStatusCode":true}
Can someone please help me on how we can set result.Content with a MemoryStream object (I have seen example of “FileStream” at other places on google to set “result.Content” but I want to use MemoryStream object only!). I am highlighting this because I think the problem lies with setting the MemoryStream object to the result.Content (in order to properly save the streams content into the result.Content object)
P.S. I have also gone thru Uploading/Downloading Byte Arrays with AngularJS and ASP.NET Web API (and a bunch of other links) but it did not help me much… :(
Any help is greatly appreciated. Thanks a lot in advance :)
I got my issue solved!!
All I did was to change the Response Type to HttpResponseMessage and use "return result" in the last line rather than Ok(result) { i.e. HttpResponseMessage Type rather than OKNegiotatedContentResult Type)

Resources