Вывести веб-форму главной страницы asp.net на электронную почту html
Привет, у меня тут небольшой кошмар!
Я пытаюсь вывести веб-форму в html, используя page.rendercontrol и htmltextwriter, но это приводит к пустому письму.
Код:
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 и добавил:
public override void
VerifyRenderingInServerForm (Control control) {return; }
Но теперь я получаю ошибку:
VerifyRenderingInServerForm (Control) ': не найден подходящий метод для переопределения
У кого-нибудь есть решение для этого? Я рву свои волосы!!
Спасибо,
Стив
5 ответов
Это то, что я делаю, в 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()
Так что я боролся с этим и, наконец, нашел ответ...
Я пытался извлечь визуализированный HTML-код GridView и поместить его в электронное письмо. Все работало идеально, когда это действие происходило на странице, но когда я переместил функциональность в пользовательский элемент управления, метод VerifyRenderingInServerForm больше не работает, поскольку это метод Page, а не метод Control.
Чтобы это исправить, вы должны переопределить метод Render и вызвать страницу, чтобы убедиться, что элемент управления отображается в форме с тегом runat = server. Вот исправление...
protected override void Render(HtmlTextWriter writer)
{
if (Page != null)
{
Page.VerifyRenderingInServerForm(this);
}
base.Render(writer);
}
Вот ЧАСЫ потраченного впустую времени прямо там, но наконец-то!
Если вам не нужно перенаправлять страницу, после рендеринга содержимого страницы (из вашего примера кода это не выглядит так, как вам нужно), то вы можете использовать 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, вы можете попробовать ее в Google. Первая статья, которую я нашел, была в VB.NET, но все еще полезна:
http://aspnetlibrary.com/articledetails.aspx?article=Use-Response.Filter-to-intercept-your-HTML
Для меня это звучит так, как будто вы можете сделать это с помощью пользовательского элемента управления, а затем преобразовать вывод пользовательского элемента управления в строку, используя следующий код:
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 в элементе управления.
Этот код был взят из блога Скотта Гатриса здесь.
С уважением
Джеспер Хауге
Это метод, который я использую, чтобы втиснуть свои веб-формы в электронную почту:
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();
}
Это поместит вашу веб-форму в строку для использования, как вы хотите. Самое замечательное то, что он тянет всю страницу, поэтому вам не придется беспокоиться о том, что теги с вашей главной страницы также не будут включены.