我的网站上有两个页面,其中填充了数据库中的内容以及用户输入的字段(不要问!)。这些页面还包含一个带有嵌套DataList的ListView。这些页面上有按钮,点击后抓取页面的html内容,将其写入HtmlTextWriter,然后获取文本并将其放入电子邮件中。
我需要做的是在放入电子邮件之前用字符串文字等价物替换html源代码中的任何TextBox / DropDownLists。
到目前为止我的aspx代码看起来像这样:
<div id="mailableContent" runat="server">
<asp:TextBox ID="txtMessage" runat="server"/>
<asp:Label ID="lblContentFromDb" runat="server"/>
<asp:ListView ID="lvwOffices" runat="server">
//loads of stuff here including more textboxes for the user to fill in
</asp:ListView>
</div>
并且代码隐藏是这样的:
StringBuilder stringBuilder = new StringBuilder();
StringWriter writer = new StringWriter(stringBuilder);
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
mailableContent.RenderControl(htmlWriter);
MailMessage message = new MailMessage();
//do more stuff to set up the message object
message.Body = stringBuilder.ToString();
//send the message
到目前为止,我的想法是1.手动将任何文本框设置为Visible = false,然后使用相应的文本框值填充文字控件,这是相当混乱和繁琐的。注意我必须删除输入控件,否则html的电子邮件需要用表单元素包装,我真的不想这样做。
有没有更好的方法来做这一切,我想也许做一些.Net1.1样式的xslt转换与xml文件中定义的页面内容可能是更好的方法来解决这个问题,但我不确定这是否会处理我的需求,我目前正在使用带有嵌套DataList的ListView。
答案 0 :(得分:1)
我发现你所描述的内容有很多开销。您的电子邮件模板是否保持不变?如果是这样,为什么不简单地使用html 3代码的简单html模板。然后只需从磁盘读取该文件,并用动态内容替换特定的peices(即## Name ##)。这样您就可以完全控制通过电子邮件发送的html,并且可以控制用户输入的内容。
这也会限制使html与电子邮件客户端兼容的工作量。
澄清:在前面的建议中,我建议UI实现和电子邮件实现是截然不同的,这反过来又允许更灵活地撰写电子邮件。不使用
mailableContent.RenderControl(htmlWriter);
这也允许您根据您的规格撰写 ListView 的内容。
答案 1 :(得分:1)
一些想法:
使用RegEx以明文替换文本框和下拉列表的html输出。 (整蛊,找到<option selected="selected">
的复杂功能。
做我做的事:
IPlainTextable
PlainTextMode
的布尔属性(默认设置为false)IPlainTextable
在扩展的webcontrols的“渲染”部分中,如果PlainTextMode
为真,则渲染出明文值。例如,对于TextBox的子类
protected override void Render(HtmlTextWriter writer)
{
if (PlainTextMode)
writer.WriteLine(this.Text);
else
base.Render(writer);
}
在渲染页面之前,请浏览所有IPlainTextable
控件并将PlainTextMode
设置为true
。
我编写了一个漂亮的小方法来迭代嵌套控件集:
public static List<T> FindControlsOfType<T>(Control ctlRoot)
{
List<T> controlsFound = new List<T>();
if (typeof(T).IsInstanceOfType(ctlRoot))
controlsFound.Add((T)(object)ctlRoot);
foreach (Control ctlTemp in ctlRoot.Controls)
{
controlsFound.AddRange(FindControlsOfType<T>(ctlTemp));
}
return controlsFound;
}
所以你会做的事情如下:
foreach (IPlainTextable ctl in FindControlsOfType<IPlainTextable>(this))
{
ctl.PlainTextMode = true;
}
然后在那之后将渲染变为字符串...