How to load mht from stream/string into a WebBrowser control? - c#

The WebBrowser control loads properly any mht file if I use the Navigate method, but when I use the DocumentText or DocumentStream properties, the source of the mht file is displayed as if I opened the file in notepad.
If I write the stream to a temp file then Navigate to it, it works properly, but I don't want to do it this way.
This issue seems common, but I didn't find a working solution for it. Some people suggest I should fool IE by implementing IPersistMoniker com interface, ...etc. I have tried with this a little bit, but unfortunately I got the same result. May be I have done something wrong. I still feel their should be a more straightforward solution (other than saving in a temp file first), any idea?

I remember I was facing the same issue a few years ago and although I searched for a solution then I did not find any. In the end, I went for the temp-file approach. I wish you good luck, and if there's an answer I would like to know too.

in vb.net we've used
Response.ContentType = "message/rfc822"
Dim ByteDocBlob() As Byte = cwWebUtil.ConvertLocalFileToByteArray(FilePath, True)
Dim HTMLText As String = System.Text.Encoding.UTF8.GetString(ByteDocBlob)
Response.Write(HTMLText)
Response.End()
Problem is only IE seems to accept it.

var uri = new Uri(String.Format("file:///{0}", Path.GetFullPath(source)));
wbMain.Navigate(uri);
where source - path to your .mht file

Related

PDFSharp saved Document always promps the "Save changes" message after filling form fields

Recently I made a program where I take a pdf file and using PDFsharp fill in the form fields with required values. The code that I made works fine it writes the values just fine but the problem comes after you open the pdf and try to close it, you will get a the standard message "Do you want to save changes before closing" even thou you just opened and close the document. The code that I use looks like this:
string templateDocPath = #"Original.pdf";
using (PdfDocument myTemplate = PdfReader.Open(templateDocPath, PdfDocumentOpenMode.Modify))
{
PdfAcroForm form = myTemplate.AcroForm;
if (form.Elements.ContainsKey("/NeedAppearances"))
{
form.Elements["/NeedAppearances"] = new PdfBoolean(true);
}
else
{
form.Elements.Add("/NeedAppearances", new PdfBoolean(true));
}
PdfTextField testField = (PdfTextField)(form.Fields["Name"]);
testField.Value = new PdfString("NameTest");
testField.ReadOnly = true;
myTemplate.Save(#"Output.pdf");
myTemplate.Close();
}
When I was trying to solved the problem I found out that the message comes only after you add "/NeedAppearances" Element to the AcroForms. You need this element or the values you write on the document will not show.
Googling some more I found a forum (https://forum.pdfsharp.net/viewtopic.php?f=2&t=3741) where someone asked the same question but didn't get a clear answer, the last comment mentioned that "/NeedAppearances" says to the document to generate the new values. So when you open the document new values are generated, so you have to save them.
I would like to know if it's true and is there a way to remove the message?
I came across this article yesterday while I was trying to find an answer for the exact problem described in the title. I was never able to find anything from any of the Google searches I ran. However, I was able to figure out what the problem was.
The issue is that when you save the PdfDocument object, it is defaulting the PDF as version 0. You can verify this by opening the generated PDF in Notepad++ (or similar text editor) and looking at the first line. When you open the PDF, Acrobat/Reader has to format it to be able to display it since it is an outdated PDF version; thus causing the document to be changed.
The solution is to set the Version of the PdfDocument before you save (an example of this can be seen here: https://forum.pdfsharp.net/viewtopic.php?f=2&t=617). As of PDFsharp version 1.50, the highest supported version is 17 (see PDFsharp Wiki on which PDF versions are supported).

How to load local html page in web form

I wish to load a local html page in my web form.
The code I'm using looks like
Response.Redirect("C:\Player\Results\xyz.html", false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
I know there are similar questions asked but none helped me.
It would be very much helpful if someone can let me know where I'm going wrong
Thank you
#m_beta you are using the physical path for redirection. This will necessiate you to change the code whenever you move your code location. Use relative path instead.
It would be something like below. You need to correct the path according to your location.
Response.Redirect("~/admin/paths.aspx", false);
Redirecting to a http / https url that will respond with the static content is one thing, but no browser is going to load a local file. If browsers did that it would introduce a massive security risk.
You can add redirection like this also
If localhost, check your localhost value add like below
Response.Redirect("http://localhost:51043/xyz.html");
Live site
Response.Redirect("http://xyzdotcom/xyz.html");
A simple way might be :
var htmlContent = System.IO.File.ReadAllText(#"C:\Player\Results\xyz.html");
Response.Write(htmlContent);
Use IFrame and use it;s SRC property to call your html page
There are many ways to do it but I would like to mention the 2 which worked for me
In this approach the response will be redirected to the page you are passing.
Response.Redirect("~/Results/xyz.html", false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
In this below mentioned approach the content of the html page which you wish to render will be read and then passed on using OutputStream.
var encoding = new System.Text.UTF8Encoding();
var htm = System.IO.File.ReadAllText(Server.MapPath("/Results/Html/") + "xyz.html", encoding);
byte[] data = encoding.GetBytes(htm);
Response.OutputStream.Write(data, 0, data.Length);
Response.OutputStream.Flush();
Thanks to everyone who has contributed here!

Need Alternative to EO.Pdf for Converting HTML to PDF in C#, wkhtmltopdf?

I am creating a HTML catalog of movies, and then converting it to PDF. I was using EO.Pdf, and it worked for my small test sample. However, when I run it against the entire list of movies, the resulting HTML file is nearly 8000 lines, and 7MB. EO.Pdf times out when attempting to convert it. I believe it is a limitation of the free version, as I can copy the entire HTML and paste it into their online demo and it works.
I am looking for an alternative to use. I am not good with command line, or running external programs, so I would prefer something I can add to the .NET library and use easily. I will admit that the use of EO.Pdf was easy, once I added the dll to the libarary and added the namespace, it took one line of code to convert either the HTML Code, or the HTML file into a PDF. The downsides I ran into were that they had a stamp on every page (in 16pt font) with their website on it. It also wouldn't pick up half of my images, not sure why. I used a relative URL in the HTML file to the images, and I created the PDF in the same dir as the HTML file.
I do not want to re-create the layout in a PDF, so I think something like iTextSharp is out. I've read a bit about something called like wkhtmltopdf or something strange like that. It sounded good, but needed a wrapper, and I have no clue how to accomplish that, or use it.
I would appreciate suggestions with basic instructions how to use them. Either a library and a couple lines on how to use it. Or if you can tell me how to setup/use the wkhtmltopdf I would be extremely greatful!
Thanks in advance!
I'm using wkhtmltopdf and I'm very happy with it. One way of using it:
Process p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "wkhtmltopdf.exe";
p.StartInfo.Arguments = "-O landscape <<URL>> -";
p.Start();
and then you can get a stream:
p.StandardOutput.BaseStream
I used this because I needed a stream, of course you can invoke it differently.
Here is also a discussion about invoking wkhtmltopdf
I just saw, that someone is implementing a c# wrapper for wkhtmltopdf. I haven't tested it, but may be worth a look.
After much searching I decided to use HiQPdf. It was simple to use, fast enough for my needs and the price point was acceptable to me.
var converter = new HiQPdf.HtmlToPdf();
converter.Document.PageSize = PdfPageSize.Letter;
converter.Document.PageOrientation = PdfPageOrientation.Portrait;
converter.Document.Margins = new PdfMargins(15); // Unit = Points
converter.ConvertHtmlToFile(htmlText, null, fileName);
It even includes a free version if you can keep it to 3 pages.
http://www.hiqpdf.com/free-html-to-pdf-converter.aspx
And no, I am in no way affiliated with them.
I recommend ExpertPdf.
ExpertPdf Html To Pdf Converter is very easy to use and it supports the latest html5/css3. You can either convert an entire url to pdf:
using ExpertPdf.HtmlToPdf;
byte[] pdfBytes = new PdfConverter().GetPdfBytesFromUrl(url);
or a html string:
using ExpertPdf.HtmlToPdf;
byte[] pdfBytes = new PdfConverter().GetPdfBytesFromHtmlString(html, baseUrl);
You also have the alternative to directly save the generated pdf document to a Stream of file on the disk.

How to download a file without extension in C#

Okay so I want to download a file from a website, but the file is lacking an extension.
(it's an image file, I know this much, but the link does not provide the actual extension)
When I use webrequest, or webclient to download the file I get a "404 file not found" exception.
WebClient wc = new WebClient();
Stream strm = wc.DownloadFile("http://some_site.some_domain/some_image.","C:/some_directory/save_name.some_extention");
Notice the lack of extention at the end of the URL.
The site in question displays the image fine in a webbrowser, but when viewing just the image there is no extension and thus it's treated an unknown file (not showing an image).
So simply put: how do I download a file if there is no extention specified?
Thanks in advance!
So you're trying to determine what extension to give the file after downloading? If the URL doesn't have one you would have to inspect the actual data of the file.
You might be able to inspect the beginning of the file and see if it matches known valid file types. For instance, PNGs seem to have 'PNG' as bytes 2-4 (at least in the ones I've inspected). By looking at that data you should be able to determine the format with a fairly high accuracy.
This would be my best suggestion, if this doesn't work I don't know how to solve you problem...
List<string> fileExtensions = new List<string>(){"png","gif","bmp","jpg"}// other known image file extensions here...
WebClient wc = new WebClient();
foreach(var extension in fileExtensions)
{
try
{ wc.DownloadFile("http://some_site.some_domain/some_image."+extension,"C:/some_directory/save_name."+extension);
break;
}
catch {}
}
This would just be a work around, I guess... Not a real solution...

How do I get a C# WebBrowser control to show jpeg files (raw)?

Does anyone know in .Net 2.0 - .Net 3.5 how to load a jpeg into a System.Windows.Forms.WebControl as a byte-array and with the right mimetypes set so it will show?
Something like:
webBrowser1.DocumentStream = new MemoryStream(File.ReadAllBytes("mypic.jpg"));
webBrowser1.DocumentType = "application/jpeg";
The webBrowser1.DocumentType seems to be read only, so I do not know how to do this. In general I want to be able to load any kind of filesource with a mimetype defined into the browser to show it.
Solutions with writing temp files are not good ones. Currently I have solved it with having a little local webserver socket listener that delivers the jpeg I ask for with the right mimetype.
UPDATE: Since someone deleted a answer-my-own question where I had info that others could use, I will add it as an update instead. (to those who delete that way, please update the questions with the important info).
Sample solution in C# here that works perfectly: http://www.codeproject.com/KB/aspnet/AspxProtocol.aspx
You have to implement an async pluggable protocol, e.g. IClassFactory, IInternetProtocol... Then you use CoInternetGetSession to register your protocol. When IE calls your implementation, you can serve your image data from memory/provide mime type.
It's a bit tedious, but doable. Look at IInternetProtocol and pluggable protocols documentation on MSDN.
You cannot do it. You cannot stuff images into Microsoft's web-browser control.
The limitation comes from the IWebBrowser control itself, which .NET wraps up.
If you want a total hack, try having your stream be the HTML file that only shows your picture. You lose your image byte stream and will have to write the image to disk.
I do not know whether the WebBrowser .NET control supports this, but RFC2397 defines how to use inline images. Using this and a XHTML snippet created on-the-fly, you could possibly assign the image without the need to write it to a file.
Image someImage = Image.FromFile("mypic.jpg");
// Firstly, get the image as a base64 encoded string
ImageConverter imageConverter = new ImageConverter();
byte[] buffer = (byte[])imageConverter.ConvertTo(someImage, typeof(byte[]));
string base64 = Convert.ToBase64String(buffer, Base64FormattingOptions.InsertLineBreaks);
// Then, dynamically create some XHTML for this (as this is just a sample, minimalistic XHTML :D)
string html = "<img src=\"data:image/" . someImage.RawFormat.ToString() . ";base64, " . $base64 . "\">";
// And put it into some stream
using (StreamWriter streamWriter = new StreamWriter(new MemoryStream()))
{
streamWriter.Write(html);
streamWriter.Flush();
webBrowser.DocumentStream = streamWriter.BaseStream;
webBrowser.DocumentType = "text/html";
}
No idea whether this solution is elegant, but I guess it is not. My excuse for not being sure is that it is late at night. :)
References:
RFC2397
Image to base64 encoded string
IE only support 32KB for inline images in base64 encoding, so not a good solution.
Try the res: protocol.
I haven't tried it with a .net dll but this post says it should work. Even if it does require a C++ dll it's much simpler to use as far as coding goes.
I've created a post that show you how here that shows you how to create the resource script and use the res: protocol correctly.

Categories

Resources