views:

252

answers:

4

Hi I'm having a bit of a nightmare here!

I'mv trying output a webform to html using page.rendercontrol and htmltextwriter but it is resulting in a blank email.

Code:

   StringBuilder sb = new StringBuilder();
   StringWriter sw = new StringWriter(sb);
   HtmlTextWriter htmlTW = new HtmlTextWriter(sw);

   page.RenderControl(htmlTW);

   String content = sb.ToString();

   MailMessage mail = new MailMessage();

   mail.From = new MailAddress("[email protected]");
   mail.To.Add("[email protected]");
   mail.IsBodyHtml = true;

   mail.Subject = "Test";
   mail.Body = content;

    SmtpClient smtp = new SmtpClient("1111");
    smtp.Send(mail);

    Response.Write("Message Sent");

I also tried it by rendering a single textbox and got and error saying It needed to be within form tags (which are on the masterpage).

I tried this fix: http://forums.asp.net/p/1016960/1368933.aspx#1368933 and added:

public override void 

VerifyRenderingInServerForm(Control control) { return; }

But now the errror I get is:

VerifyRenderingInServerForm(Control)': no suitable method found to override

Does anyone have a fix for this? I'm tearing my hair out!!

Thanks,

Steve

A: 

This is what I do, in vb:

Dim sw as New StringWriter()
Dim writer as New HtmlTextWriter(sw)
System.Web.HttpContext.Current.Server.Execute("YourPage.aspx", writer)
Dim message as String = sw.ToString()
Barry
Thanks for your help. I tried this method but couldn't get it to work. It would just get in a loop and output the same text over and over again. I don't think I implemented it correctly though
Steve McCall
This isn't called from the page I'm trying to render, but from somewhere else in the code, usually in a business layer.
Barry
+1  A: 

Hi,

If you don't need to redirect the page, after you render the contents of the page (from your code sample, it doesn't look like you need to), then you may want to use a Response.Filter.

Off the top of my head, it would look something like:

protected void Page_Load(object sender, System.EventArgs e) 
{
   Response.Filter = new SmtpFilter(Response.Filter);
}

The SmtpFilter class, is just a class that inherits from the Stream object.

The main method will be the Write method. Here is some code off the top of my head to Override the Write(...) method, send the Smtp mail, and continue on processing.

    public override void Write(byte[] buffer, int offset, int count) {
    // get the html
    string content= System.Text.Encoding.UTF8.GetString(buffer, offset, count);

   MailMessage mail = new MailMessage();  

   mail.From = new MailAddress("[email protected]");  
   mail.To.Add("[email protected]");  
   mail.IsBodyHtml = true;  

   mail.Subject = "Test";  
   mail.Body = content;  

    SmtpClient smtp = new SmtpClient("1111");  
    smtp.Send(mail);  


    buffer = System.Text.Encoding.UTF8.GetBytes(HTML);
    this.Base.Write(buffer, 0, buffer.Length);    
    }

If you need more help on Response.Filters, you may want to google it. The first article I found was in VB.NET, but still helpful:

http://aspnetlibrary.com/articledetails.aspx?article=Use-Response.Filter-to-intercept-your-HTML

Cheers!

Dave

dave wanta
Hi, thanks a lot for this answer. It looks like what I need. Will it output the values entered by the user filling in the form?I'll try this out on Monday and let you know how I get on.
Steve McCall
If the form has been posted back, then yes. This is one of the lasts steps in the Response pipeline, so you will get what is being sent to the browser (javascript and all -- so, you will need to be sure to remove any script from your email).
dave wanta
Ok, I've tried this and get a error stating that the smtpfilter doesn't exist.Also that there is no definition for 'Base' Any ideas?
Steve McCall
You have to create your own SmtpFilter class. Check out the article I linked too. They called their class "ReplaceHTML". It inherits from the Stream class.
dave wanta
OK, I'll look at that, thanks!
Steve McCall
A: 

This is the method I use to cram my webforms into an email:

private string HtmlPageInToString()
{
WebRequest myRequest;
myRequest = WebRequest.Create(@"http://yoururlhere/");

myRequest.UseDefaultCredentials = true;

WebResponse myResponse = myRequest.GetResponse();

Stream ReceiveStream = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");

StreamReader readStream = new StreamReader(ReceiveStream, encode);

return readStream.ReadToEnd();
}

This will stuff your webform into a string for use how ever you would like. The great thing is that it pulls in the whole page so you won't have to worry about the tags from your masterpage not being included also.

kaelle
I tried this but the values entered into the text boxes are lost.
Steve McCall
And you are not storing the input from the text boxes anywhere?
kaelle
A: 

To me this sounds like you could do this with a user control, and then render the user control output into a string using the following code:

public class ViewManager {
    public static string RenderView(string path, object data) {
            Page pageHolder = new Page();
            UserControl viewControl = (UserControl) pageHolder.LoadControl(path);

            if (data != null) {
                    Type viewControlType = viewControl.GetType();
                    FieldInfo field = viewControlType.GetField("Data");
                    if (field != null) {
                            field.SetValue(viewControl, data);
                    }
                    else {
                            throw new Exception("ViewFile: " + path + "has no data property");
                    }
            }

            pageHolder.Controls.Add(viewControl);
            StringWriter result = new StringWriter();
            HttpContext.Current.Server.Execute(pageHolder, result, false);
            return result.ToString();
}

This code fires all the normal events in the control, and you can load the posted form data into the via a Data property in the control.

This code was lifted from Scott Guthries blog post here.

Regards

Jesper Hauge

Hauge