输出asp.net主页webform到html电子邮件

时间:2010-03-19 11:38:21

标签: c# asp.net rendercontrol

嗨,我在这里做了一个噩梦!

我尝试使用page.rendercontrol和htmltextwriter将webform输出到html,但这会产生一封空白的电子邮件。

代码:

   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("test@test.com");
   mail.To.Add("steve@test.com");
   mail.IsBodyHtml = true;

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

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

    Response.Write("Message Sent");

我也通过渲染单个文本框来尝试它并得到并且错误说它需要在表单标记内(在主页上)。

我尝试了此修复程序:http://forums.asp.net/p/1016960/1368933.aspx#1368933并添加了:

public override void 

VerifyRenderingInServerForm(控件控件) {    返回; }

但现在我得到的错误是:

VerifyRenderingInServerForm(Control)':找不到合适的方法来覆盖

有人对此有解决方法吗?我正在撕扯我的头发!!

谢谢,

史蒂夫

5 个答案:

答案 0 :(得分:4)

这就是我所做的,在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()

答案 1 :(得分:1)

如果您不需要重定向页面,在渲染页面内容后(从您的代码示例中,它看起来不像您需要),那么您可能需要使用Response.Filter。

从头顶看,它看起来像是:

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

SmtpFilter类只是一个继承自Stream对象的类。

主要方法是Write方法。这里有一些代码,我首先要覆盖Write(...)方法,发送Smtp邮件,然后继续处理。

    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("test@test.com");  
   mail.To.Add("steve@test.com");  
   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);    
    }

如果您需要有关Response.Filters的更多帮助,您可能需要谷歌搜索。我发现的第一篇文章是在VB.NET中,但仍然有用:

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

答案 2 :(得分:1)

所以我正在努力解决这个问题,最终找到答案......

我试图提取GridView的呈现HTML并将其放入电子邮件中。当该操作在页面上发生时,一切都很完美,但当我将功能移动到用户控件时,VerifyRenderingInServerForm方法不再有效,因为它是一个Page方法,而不是一个Control方法。

要解决此问题,您必须覆盖Render方法并调用Page以确保在具有runat = server标记的表单中呈现控件。这是修复...

protected override void Render(HtmlTextWriter writer)
{
    if (Page != null)
    {
        Page.VerifyRenderingInServerForm(this);
    }
    base.Render(writer);
}

这就浪费了很多时间,但终于来了!

答案 3 :(得分:0)

这是我用来将我的网络表格塞进电子邮件的方法:

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();
}

这会将您的webform填充到一个字符串中,以供您按照自己的意愿使用。最棒的是,它会拉入整个页面,因此您不必担心主页中的标记也不会被包含在内。

答案 4 :(得分:0)

对我而言,这听起来像是可以使用用户控件执行此操作,然后使用以下代码将用户控件输出呈现为字符串:

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();
}

此代码触发控件中的所有正常事件,您可以通过控件中的Data属性将发布的表单数据加载到该文件中。

此代码取自Scott Guthries blog post here

此致

Jesper Hauge