I need to create a PDF file in memory within a web API and send it. I do create the PDF and the web API sends it, but I can't open it once received.
I do create the PDF as a byte array with this:
private byte[] createPDF()
{
MemoryStream memStream = new MemoryStream();
byte[] pdfBytes;
Document doc = new Document(iTextSharp.text.PageSize.LETTER);
PdfWriter wri = PdfWriter.GetInstance(doc, memStream);
doc.AddTitle("test");
doc.AddCreator("I am");
doc.Open();//Open Document to write
Paragraph paragraph = new Paragraph("This is my first line using Paragraph.");
Phrase pharse = new Phrase("This is my second line using Pharse.");
Chunk chunk = new Chunk(" This is my third line using Chunk.");
doc.Add(paragraph);
doc.Add(pharse);
doc.Add(chunk);
pdfBytes = memStream.ToArray();
doc.Close(); //Close
return pdfBytes;
}
This method is called by the method in the web API which sends the PDF, and it is this one:
[HttpGet]
public HttpResponseMessage GetFiniquitopdf()
{
try
{
byte[] buffer = createPDF();
response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(new MemoryStream(buffer));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentLength = buffer.Length;
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "myFirstPDF.pdf"
};
}
catch (Exception e)
{
response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message);
}
return response;
}
The problem is when the PDF is downloaded it is useless, can't be opened, I don't understand why the PDF can't be opened, I thought it was the security of the Windows 10, so once downloaded I do check it as a secure file, but it doesn't open anyway.
I guess there is something wrong in the way I send it or maybe I lack of something in the creation of the PDF file
thanks in advance
You retrieve the bytes from the memory stream before closing the document:
pdfBytes = memStream.ToArray();
doc.Close(); //Close
return pdfBytes;
But the pdf in the memory stream is not complete before the document is closed. Thus, simply switch the order of instructions:
doc.Close(); //Close
pdfBytes = memStream.ToArray();
return pdfBytes;
Related
I am trying to generate pdf file using c# web api using the following code :
i have tried to change in the web.config but it didn't help.
[HttpGet]
public HttpResponseMessage Generate()
{
var stream = new MemoryStream();
// processing the stream.
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(stream.ToArray())
};
result.Content.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "CertificationCard.pdf"
};
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
I expected download pdf directly to my local disk but non worked.
I have a requirement to show PDF files in a browser. I use Spring MVC. Is there a way I can do this without using AbstractPdfView? I do not want to render the PDF at runtime. All the PDF files will be stored in my webserver.
This is the code I am using. But this directly downloads the file instead of showing it up in a browser.
#RequestMapping(value = "/download" , method = RequestMethod.GET)
public void doDownload(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// get absolute path of the application
ServletContext context = request.getSession().getServletContext();
String appPath = context.getRealPath("");
String filename= request.getParameter("filename");
filePath = getDownloadFilePath(lessonName);
// construct the complete absolute path of the file
String fullPath = appPath + filePath;
File downloadFile = new File(fullPath);
FileInputStream inputStream = new FileInputStream(downloadFile);
// get MIME type of the file
String mimeType = context.getMimeType(fullPath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/pdf";
}
System.out.println("MIME type: " + mimeType);
String headerKey = "Content-Disposition";
response.addHeader("Content-Disposition", "attachment;filename=report.pdf");
response.setContentType("application/pdf");
// get output stream of the response
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
// write bytes read from the input stream into the output stream
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
}
Remove the line
response.addHeader("Content-Disposition", "attachment;filename=report.pdf");
This line precisely tells the browser to display a download/save dialog rather than displaying the PDF directly.
Oh, and make sure to close the input sytream in a finally block.
I'm new in programming in Windows Phone (and StackOverflow tbh). Currently, I'm working on a task that concerns with sending images stored in the Windows Phone's storage (with Exif info) to a Java server. So far I have successfully send the byte stream from the Windows Phone client and construct the image on the Java side, however, the Exif information is somehow lost. I believe it's just the way I send it on Windows Phone that's causing the problem. Very much appreciated for any help or guidance !
Here's my code on the Windows Phone client:
// Windows Phone Client code (MainPage.xaml.cs)
// This function is called when an image is selected from
// the task PhotoChooserTask ptask, which brings
// a popup that allows the user to choose an image
// from the phone's storage
void ptask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK && e.ChosenPhoto != null)
{
//Take JPEG stream and decode into a WriteableBitmap object
App.CapturedImage = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
// Attempt to send the image
WriteableBitmap pic = new WriteableBitmap(App.CapturedImage);
MemoryStream stream = new MemoryStream();
pic.SaveJpeg(stream, App.CapturedImage.PixelHeight, App.CapturedImage.PixelWidth, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
client.Send(stream);
// Close the socket connection explicitly
client.Close();
}
}
Here's the code in the SocketClient.cs
public string Send(MemoryStream data)
{
byte[] msData = data.ToArray();
if (_socket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
// Set properties on context object
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventArg.UserToken = null;
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
_clientDone.Set();
});
// Add the data to be sent into the buffer
socketEventArg.SetBuffer(msData, 0, msData.Length);
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Send request over the socket
_socket.SendAsync(socketEventArg);
}
else
{
response = "Socket is not initialized";
}
return response;
}
On the Java Server,
public static void main(String[] args) {
ServerSocket serverSocket;
Socket client;
try {
serverSocket = new ServerSocket(PORT_NUMBER);
while (true) {
client = serverSocket.accept();
// Extract exif info
InputStream inputStream = client.getInputStream();
InputStream stream = new BufferedInputStream(inputStream);
// Create file from the inputStream
File file = new File("image.jpg");
try {
OutputStream os = new FileOutputStream(file);
byte[] buffer = new byte[4096];
for (int n; (n = stream.read(buffer)) != -1;) {
os.write(buffer, 0, n);
}
}
The output image is identical to the one sent from the windows phone, just without any Exif information whatsoever. Anyone could point out what I did wrong that causes the information to be lost? I'm guessing because I called the SaveJpeg function in the windows phone code, rewriting the image file, and losing all information there, but I don't know how else to convert the image to byte and stream it.
Much help is appreciated ! Thank you.
I found the answer to my own problem. For those of you who might have a problem with this. I simply use:
Byte[] imageData = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Position = 0;
e.ChosenPhoto.Read(imageData, 0, imageData.Length);
Then send the byte array in my send function:
socketEventArg.SetBuffer(imageData, 0, imageData.Length);
I have a WP7 app where I'm trying to reconstruct an HTTPWebRequest that I have successfully written elsewhere using the synchronous methods (pasted at end) but which doesn't work in WP7, I assume because I'm doing something wrong with the Asynchronous versions of these methods.
I believe the issue stems from the fact that the non-working code on the Compact Framework can only send a bytearray[] - I don't have the option of sending the json string. If I send a bytearray in the code that works, I get an error there too. Is there a different option?
Here is my code - this does not work. The exception is thrown on the 2nd line of the last method - "Using(var respons ...)":
public void CreateUser()
{
var request = (HttpWebRequest)WebRequest.Create("http://staging.cloudapp.net:8080/api/users/");
request.Method = "POST";
request.ContentType = "text/json; charset=utf-8";
request.BeginGetRequestStream(new AsyncCallback(RequestCallback), request);
}
private static void RequestCallback(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream postStream = request.EndGetRequestStream(result))
{
User user = new User("Windows", "Phone", "USCA");
Formatting formatting = new Formatting();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
string json = JsonConvert.SerializeObject(user, formatting, settings);
byte[] byteArray = Encoding.UTF8.GetBytes(json);
postStream.Write(byteArray, 0, json.Length);
}
request.BeginGetResponse(new AsyncCallback(ResponseCallback), request);
}
private static void ResponseCallback(IAsyncResult result)
{
var request = (HttpWebRequest)result.AsyncState;
using (var response = (HttpWebResponse)request.EndGetResponse(result))
{
using (Stream streamResponse = response.GetResponseStream())
{
StreamReader reader = new StreamReader(streamResponse);
string responseString = reader.ReadToEnd();
reader.Close();
}
}
}
This code works (non-compact framework version of the same request):
HttpWebRequest request = HttpWebRequest.Create("http://staging.cloudapp.net/api/users/") as HttpWebRequest;
request.Method = "POST";
request.ContentType = "text/json";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
User user = new user("Other", "Guy", "USWC");
Formatting formatting = new Formatting();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
string json = JsonConvert.SerializeObject(user, formatting, settings);
writer.Write(json);
}
var response = request.GetResponse() as HttpWebResponse;
using (var reader = new StreamReader(response.GetResponseStream()))
{
var responseText = reader.ReadToEnd();
return responseText;
}
thanks for any help!
looks like the server is responding with a "404 not found". Does the resource you are requesting exist at the server?
Does your JSON contain any non 7-bit ASCII characters, as you are currently doing:
byte[] byteArray = Encoding.UTF8.GetBytes(json);
postStream.Write(byteArray, 0, json.Length);
The number of bytes might not be identical to the number of characters in your string, which could lead to a malformed request.
It would be worthwhile using something like Fiddler to verify what is actually going over the wire from the emulator or phone (there are instructions on the Fiddler website for how to do this)
Well - I'm not sure why this problem went away. I liked #RowlandShaw's suggestion, but I didn't actually change anything in the json. Wish I could give a better solution.
I'm using the Blackberry JDE (9000 simulator), and am wondering if I can display an image from the web.
Currently, I'm seeing tutorials that use Bitmap.getBitmapResource to display images that are local to the blackberry application, but looking at the API, I'm not seeing any support for giving a web URL.
Are there other Blackberry image classes I can check out? Or is this feature just not supported?
You can download image using HTTPConnection and InputStream, create EncodedImage from stream and then display it.
See coderholic - Blackberry WebBitmapField
BTW, you can use IOUtilities.streamToBytes() method to read bytes from InputStream directly!
Here is a code example for your problem:
HttpConnection httpConn = null;
InputStream inputStream = null;
int ResponseCode = HttpConnection.HTTP_OK;
byte[] ResponseData = null;
try {
httpConn = (HttpConnection) Connector.open(url, Connector.READ, true);
ResponseCode = httpConn.getResponseCode();
if (ResponseCode == HttpConnection.HTTP_OK) {
inputStream = httpConn.openInputStream();
ResponseData = IOUtilities.streamToBytes(inputStream);
}
}
catch(IOException e){
throw new IOException("HTTP response code: "
+ ResponseCode);
}
finally {
try {
inputStream.close();
inputStream = null;
httpConn.close();
httpConn = null;
}
catch(Exception e){}
}
return ResponseData;
If you want code that made to exactly do this (though this post is old, so I'm guessing you don't anymore)
Here