I'm still having the same issue that was previously reported and answered under Microsoft Edge PDF inline issue even though I'm not using the pre-release version of Win 10, but the latest downloaded though Windows Update.
After upgrading my Win 8.1 Machine to Win 10, and tested my ASP.NET application, I faced an issue with displaying inline pdf files.
Here's my C# code in my ASP.NET application:
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition","inline;filename=some.pdf");
Response.BinaryWrite(pdfArray);
Response.End();
The above works on all browsers, except on Edge where it gives me the following error:
Couldn’t open PDF
Something’s keeping this PDF from opening.
What am I doing wrong?
Copied from my workaround on Microsoft Connect.
WARNING: This is a complete hack and runs the risk of breaking if/when Microsoft ever fixes this issue.
You'll see that Edge issues two requests whenever you view a PDF. To me, it looks like the browser is sending the initial request and then the PDF viewer is issuing its own request when it is opened. If you look at the headers in that second request, you'll see an odd DLNA header coming down, which should just be for media streaming, but that leads me to my workaround...
When the request is received in your handler or page, check if the user agent string contains "Edge/12." If it doesn't, send your PDF back normally. If it does, move on to step #2.
Check if the HTTP Header "GetContentFeatures.DLNA.ORG" exists. If it doesn't, that means that the request came from the browser. Just send back a Content-Type header of "application/pdf" and an empty body. If the header exists, then the request came from the PDF viewer and you can send your PDF back normally.
Basically, the handler treats that first request as a HEAD request and then responds with the full PDF if we determine that the request is coming from the PDF viewer. The risk we run here is if Microsoft removes that DLNA header later on, Edge will not render the PDF properly. Hopefully, Microsoft will fix this issue in their browser and this workaround will not be necessary.
Thanks Dark Helmet, you saved my day.
I implemented the solution in java. Here is the code that might help others.
String userAgent = request.getHeader("user-agent");
System.out.println(userAgent);
if(userAgent.contains("Edge")){
String dlnaHeader = request.getHeader("getcontentfeatures.dlna.org");
System.out.println(dlnaHeader);
if(dlnaHeader == null ){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] result = baos.toByteArray();
response.setContentType("application/pdf");
response.setHeader("Content-disposition","inline; ");
response.setContentLength(result.length);
ServletOutputStream sos = response.getOutputStream();
sos.write(result);
return null;
}
}
Thanks guys, I just want to put my VB.NET solution here based on your workaround.
Response.Clear()
Response.ClearHeaders()
Response.ClearContent()
Response.Buffer = True
If Request.Headers.Item("User-Agent").Contains("Edge") _
AndAlso IsNothing(Request.Headers.Item("GetContentFeatures.DLNA.ORG")) Then
'Edge? Send empty output if special header not exist
Response.ContentType = "application/pdf"
Dim bTemp As Byte()
Response.BinaryWrite(bTemp) 'Empty output
Response.Flush()
Response.SuppressContent = True
HttpContext.Current.ApplicationInstance.CompleteRequest()
End If
'Normal process:
Response.ContentType = "application/pdf"
Response.BinaryWrite(pdfArray)
Response.Flush()
Response.SuppressContent = True
HttpContext.Current.ApplicationInstance.CompleteRequest()
With Edge 16.16299 (Windows Fall Creator Update) there were made changes here. We did the workaround described in this issue and it worked "well". But now with the new version of Edge (16.16299) it isn’t working anymore and it happens, that the PDFs are corrupted (0 bytes large). Take care if you implemented this workaround somewhere.
What you also take care of is that Edge is doing two requests like before.
Related
im trying to get a PDF with the ReportLab Module which works fine so far. My problem is that im saving the PDF with the .build()-method in my Webapps directory. What i want is that i can send the PDF for downloading without saving it before. That is somehow possible with the wkhtmltopdf module, but i dont want to use any other servers for this.
The process would be like: User presses a button 'download as pdf', a pdf is generated and instant returned as a download without saving it first.
Do you know if this is possible?
You want to create the PDF server side, return it to the client, without saving the PDF (for example, in S3)?
Yes, this is possible, you create the PDF in memory using
buffer = io.BytesIO()
myPDF = canvas.Canvas(buffer, pagesize=letter)
Then after creating your pdf you save it using
myPDF.save()
buffer.seek(0)
Then when you are ready to return the PDF as a reponse you can return it with:
response = HttpResponse(buffer, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="{}"'.format("myFile.pdf")
return response
I was wondering if anyone knew of a way to save the resulting PDF document to the server, instead of prompting the user to download it locally?
Using this:
http://www.cloudformatter.com/CSS2Pdf
Many thanks
Edit:
I am using the following JS to initiate the PDF.
$(function(){
$('#generatePDF').click(function(e) {
e.preventDefault();
var pdfdata = xepOnline.Formatter.Format('printableInvoice',
{
pageWidth:'216mm',
pageHeight:'279mm',
render: 'base64'
}
);
console.log(pdfdata);
});
});
Leaving the answer in place as the comments below are relevant. The original answer was how to get the source information (using the "base64" option), not the final PDF.
So to get the final PDF that is in memory, if you examine the code in Github:
https://github.com/Xportability/css-to-pdf/blob/master/js/xepOnline.jqPlugin.js
starting at the "else" at line 602 ... this "else" is executed if you force anything other than a download. If you chose "newwin" or "embed" as the method and the browser sniffing JS did not force it back to download (it does on Safari, IE and also mobile browsers), then this "else" is executed.
On a successful AJAX post, the function "xepOnline.Formatter.__postBackSuccess" is executed. This function starts at line 863. At line 865, the base64 encoded bytes of the actual PDF are loaded. If you debug your site and debug at that line of code, you can get the value of the var "base64" which will be the base64 encoded bytes.
So, if you only had Firefox and Chrome to consider, then you could do some mod to the code to post the result back to the server and not display it. If you have all those browsers to consider, you will need to add some option (like say option:'memory' which skips all browser sniffing, runs the AJAX version but with its own success function.
I can look at adding this to the library but you are free to pull it and make some mods yourself.
I have created a windows store application and I want the user to open Documents, Excel files and picture from the app. I want the files to open in their default application. i.e. Docs in word and pictures in windows picture viewer.
I have used the following code:
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".Doc");
openPicker.FileTypeFilter.Add(".Docx");
openPicker.FileTypeFilter.Add(".png");
openPicker.FileTypeFilter.Add(".jpg");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file!=null)
{
await Windows.System.Launcher.LaunchFileAsync(file);
}
When I run this and browse to a word document the file opens up fine using word, great.
But if I browse to an image file, it doesn't do anything. I don't get any errors.
Any ideas what I need to do?
Thanks
There is no error and, simply, nothing happens? That's strange.
Here's my go-to syntax, but it's basically yours:
Let's consider what should happen. When you "launch" a docx you are basically asking the default viewer to open for that file, in that case Word. With an image you are asking the image viewer to launch. Should it work? Yes.
Launching a docx when Word is not installed should not result in the behavior your are seeing. No. You should get prompted to find a viewer in the Store. Same with an image. Even without a viewer you should get something.
Not to be a dork here, but have you rebooted? It really sounds more like something strange has happened. You might also try appending "file:///" to the front of the URL to perhaps invoke the file viewer more explicitly. None of that should be necessary however.
Best of luck
One other thing you can do is to force app picker if default program could not be launched like following:
if (file != null)
{
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = true;
bool success = await Windows.System.Launcher.LaunchFileAsync(file, options);
}
Alright, long story short. I'm developing software similar to the devices UPS delivery divers use. We have to ways to get a proof of delivery(POD). The first is a signature and the second is a picture taken by the camera.
Now the device that is capturing these images sends them to a web service we have which then goes and saves them on the server. The device saves these two as different file types, png for the signature and jpg for the picture, but the web service saves them as jpg files. Currently the signatures are working but the pictures keep throwing an exception "generic exception occurred gdi+".
I don't understand why one will save just fine but the other keeps throwing the error message. Especially since they both use the same code when they are on the server side.
I've gone searched throw the stack overflow and haven't found anything that solves my issue and I've googled to no avail. Anyone have any suggestions on what to do to get the pictures to save?
Device logic to turn the image into a string so it can be sent to the web service.
**Picture from camera logic**
Using MS As New System.IO.MemoryStream(), BM As New Bitmap(ImagePath)
BM.Save(MS, System.Drawing.Imaging.ImageFormat.Jpeg)
ImageString = Convert.ToBase64String(MS.ToArray())
End Using
**Signature logic**
Using MS As New System.IO.MemoryStream(), BM As New Bitmap(ImagePath)
BM.Save(MS, System.Drawing.Imaging.ImageFormat.png)
ImageString = Convert.ToBase64String(MS.ToArray())
End Using
Web Service logic to turn image back into string, then save it as jpeg.
Dim Image As Drawing.Bitmap = Nothing
Dim ByteImage As Byte()
If ImageString.IsNullOrEmpty = False Then
ByteImage = Convert.FromBase64String(ImageString)
Using stream As New MemoryStream(ByteImage, 0, ByteImage.Length)
stream.Write(ByteImage, 0, ByteImage.Length)
Image = CType(Drawing.Bitmap.FromStream(stream, True), Drawing.Bitmap)
End Using
Image.Save(FileLocation,Drawing.Imaging.ImageFormat.Jpeg)
End If
That Image.Save is what is throwing the exception.
It appears that you save the image to some media on the phone, then you read it again and send it. Don't do that. Just save it, base 64 encode the whole file, send that base 64 encoded string.
I have a little piece of code that seems to be a textbook example of saving files from Silverlight 4.0, but it doesn't seem to work.
The following snippet comes from a button click handler:
var saveDialog = new SaveFileDialog() { Filter = "All Files(*.*)|*.*" };
if (saveDialog.ShowDialog() == true)
{
using (var stream = saveDialog.OpenFile())
using (var writer = new StreamWriter(stream))
{
writer.WriteLine("Hello, World!");
writer.Flush();
writer.Close();
}
}
I've tried saving a file to many different locations, all with the same behavior:
The SaveFileDialog appears to behave normally.
The SaveFileStream appears (from the debugger) to behave normally.
After the call to writer.Flush(), the BaseStream advances to position 15.
No exception is thrown.
After the block executes, I cannot find the file using Windows Explorer.
It seems to me that the code is too simple to fail under normal circumstances. So that leads to my question: what is amiss with my circumstances? Why is it that the save appears to complete successfully, but the file is nowhere to be found? Security settings? The code itself? I'm at a loss.
Update
I've tried a few more things, and still no luck. I ran the application out-of-browser with the same symptoms, promoted the SaveFileDialog to a class variable. The application behaves like there is no error, but no file appears in the save location (my Documents folder, in Vista).
The Plot Thickens
I was stepping through with the debugger and found additional strange behavior. After the call to saveDialog.OpenFile(), the file appears at the target location. It remains after each statement, but is removed after the call to writer.Close(). Why on earth would the file be automagically deleted when the stream closes?
Thanks in advance for your help!