I want to convert an aspx page to PDF using a component that can convert Html to PDF. Is it possible to, during post back, redirect the output from the aspx-page and send it as a stream or string to a HtmlToPdf method?
protected override void Render(HtmlTextWriter writer)
{
// setup a TextWriter to capture the page markup
TextWriter tw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(tw);
// render the page into our surrogate TextWriter
base.Render(htw);
// convert the TextWriter markup to a string
string pageSource = tw.ToString();
if (convertToPDF)
{
// convert the page markup to a pdf
// eg, byte[] pdfBytes = HtmlToPdf(pageSource);
}
// write the page markup into the output stream
writer.Write(pageSource);
}
Have you tried to send the value returned from "HttpContext.Current.Response.OutputStream;" in the postback ?
Hi I think that the way to do this would be to use the Reponse.Filter property to intercept and alter the HTML being sent to a page.
There's a tutorial video and sample code in both VB.net and C# on this page on the ASP.net website:
http://www.asp.net/learn/videos/video-450.aspx
You would write an HttpFilter that is attached to the request. This is code that can change the output after it has been written by the ASP.NET Page's Render step.
This article shows how to do this (they change the output from HTML to valid XHTML, but the idea is the same).
Related
Is there any Possibility that it can Generate Compressed HTML from the GridVIew ???
I do not suggest to do that, but I can give an idea for how I will try to do that:
You can render the GridView in a string, make the compression and then show it to the page.
TextWriter stringWriter = new StringWriter();
HtmlTextWriter GrapseMesaMou = new HtmlTextWriter(stringWriter);
cGridView.RenderControl(GrapseMesaMou);
// this is the string that you show on page (eg place it on a literal)
string cFinalResults = CompressHtml(stringWriter.ToString());
// not show it any more...
cGridView.Visible = false;
one html compressor: http://code.google.com/p/htmlcompressor/
I do not know if this can work smoothly for all cases, but you can give it a try to see if it is what you look for.
Can ASCX or ASP.net files be saved as HTML files? if so, how?
yes, it is possible, to get the rendered content of a User Control, do the following :
StringWriter output = new StringWriter();
Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl("path to ascx file");
pageHolder.Controls.Add(viewControl);
HttpContext.Current.Server.Execute(pageHolder, output, true);
string htmlOutput = output.ToString();
Am sure you can adapt the above for ASPX page if required :-)
From there, saving that to a file should be fairly straight forward.
HTH.
D
You can do this directly with the Render method of a Page or UserControl. Since the method is protected, you will need to create a control that subclasses either. From there, you've got access to do whatever you need.
e.g.
public partial class MyPage: Page
{
public string GetPageContents()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (HtmlTextWriter writer = new HtmlTextWriter(sw))
{
Render(writer);
}
return sb.ToString();
}
}
You probably wouldn't want to call this anytime before the PreRenderComplete event of the page though, since otherwise you can't be sure all child controls/events/etc have finished.
I'd like to know one (or more) ways to parse the HTML page output. I'd like to detect some patterns on the HTML that will be send to the client and log some info if present.
Everything you need is in the
Page.Render
method, override it and do what you want to in there.
protected override void Render(HtmlTextWriter writer)
{
// do your stuff here
StringBuilder stringBuilder = new StringBuilder();
StringWriter stringWriter = new StringWriter(stringBuilder);
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlTextWriter); // <-- render the page into the htmlTextwriter
// the htmlTextwriter connects trough the stringWriter to the stringBuilder
string theHtml = stringBuilder.ToString(); // <---- html captured in string
//---------------------------------------------
//do stuff on theHtml here
//---------------------------------------------
writer.Write(theHtml); // <----write html with the original writer
}
It depends on what you mean by "parse" exactly, but something like the HTML Agility Pack can create an XML-like structure from an HTML document - essentially creating a proper HTML DOM data structure. You can even then convert it straight to XML, use LINQ, etc.
I have a HTML page that I have created that essentially consists of:
<div>
<table>
<tr>
<td><asp:label runat="server" id="someText"></asp:label></td>
</tr>
</table>
</div>
The label text is generated on page load from an SQL query.
The above is a very basic and simplified version of what I have on my page.
What I'd like to achieve is to be able to e-mail the entirety of the rendered HTML page without having to build the page again in my code-behind to send it.
Is there a way of doing this?
Thanks in advance for any help.
Something like this maybe (haven't tested):
StringBuilder sb = new StringBuilder();
HtmlTextWriter hw = new HtmlTextWriter(new System.IO.StringWriter(sb));
this.Render(hw);
MailMessage message = new MailMessage();
message.IsBodyHtml = true;
message.Body = sb.ToString();
(new SmtpClient()).Send(message);
If you want to send the email as you render the page, without rerunning the page lifecycle, try the following.
Make a wrapper stream class that inherits Stream and contains two additional streams, and override its Write method to write to both streams. I don't think you need to override anything else except the Can_Whaterver_ properties, but I'm not sure.
Make a field in your Page class of type MemoryStream to hold a copy of the response.
Then, handle the page's PreInit event and set the Response.Filter, like this:
Response.Filter = new CopierStream(Response.Filter, responseCopy);
//`CopierStream` is the custom stream class; `responseCopy` is the MemoryStream
Finally, override the Page's Render method, and, after calling base.Render, you can send responseCopy by email using the SmtpClient class.
This is a very complicated technique that you should only do if you really don't want to re-run the page lifecycle.
Whichever way you do it, if your page has any images or hyperlinks, make sure that their urls include the domain name, or else they won't work in the email.
Use a webclient:
Dim wc As New WebClient
Dim str As String = wc.DownloadString("yoururl.com")
SendEmail(str) ' your email method '
I want to send emails in HTML format. How can I use asp.net to generate HTML content for emails.
Using output of .aspx page(Tried there was nothing in email body. Must be something in page that can't be used for email)
Using Webcontrol and get web control output and use it as email body.
Using custom http handler so can call handler to get email body.
Can you please suggest what would be the best solution?
Some guide or sample reference would be great if know one.
Thanks for all answers:
I am implementing code below:
string lcUrl = "http://localhost:50771/webform1.aspx";
// *** Establish the request
HttpWebRequest loHttp =
(HttpWebRequest)WebRequest.Create(lcUrl);
// *** Set properties
//loHttp.Timeout = 10000; // 10 secs
loHttp.UserAgent = "Code Web Client";
// *** Retrieve request info headers
HttpWebResponse loWebResponse = (HttpWebResponse)loHttp.GetResponse();
Encoding enc;
try
{
enc = Encoding.GetEncoding(loWebResponse.ContentEncoding);
}
catch
{
enc = Encoding.GetEncoding(1252);
}
StreamReader loResponseStream =
new StreamReader(loWebResponse.GetResponseStream(), enc);
string lcHtml = loResponseStream.ReadToEnd();
loWebResponse.Close();
loResponseStream.Close();
I think the ASPX file will make the most easy to edit mechanism. You can use
var stream = new MemoryStream();
var textWriter = new StreamWriter(stream);
Server.Execute("EmailGenerator.aspx", textWriter);
to capture the output of that page.
I personally don't like any of your options. I would probably do it by using an HTML file (or a template stored in a database) and substituting something like {{name}} with the appropriate parameter.
I did this, essentially we had a page that the user could view, and then they could click a button and send the html on the page in an email. Basically my page was responsible for generating the email. I did this by overriding the Render method, and providing my own stream or using the one passed to us. We did this dpeneding on if we were rendering what the user would see or emailing it.
protected override void Render(HtmlTextWriter writer)
{
if (_altPrintMethod)
{
System.Net.Mail.MailMessage....
mailMsg.Body=RenderHtml(baseUrl);
}
}
protected virtual string RenderHtml(string baseUrl)
{
RemapImageUrl(baseUrl);
StreamWriter sw = new StreamWriter(new MemoryStream());
HtmlTextWriter writer = new HtmlTextWriter(sw);
base.Render(writer);
writer.Flush();
StreamReader sr = new StreamReader(sw.BaseStream);
sr.BaseStream.Position = 0;
return sr.ReadToEnd();
}
One thing to note is you have to make sure all links are fully qualified. You might be able to use the base functionality. this is what I was doing in the RemapImageUrl basically I appended an absolute path on all my image files.