Asp.Net页面的电子邮件内容

Asp.Net页面的电子邮件内容,asp.net,email,Asp.net,Email,我在我的网站上有两个页面,其中填充了来自数据库的内容,还有用户输入的字段(不要问!)。这些页面还包含一个带有嵌套数据列表的ListView。这些页面上有一些按钮,单击这些按钮可以获取页面的html内容,将其写入HtmlTextWriter,然后获取文本并将其发送到电子邮件中 我需要做的是将html源中的任何文本框/下拉列表替换为字符串文本等价物,然后再放入电子邮件 到目前为止,我的aspx代码如下所示: <div id="mailableContent" runat="server">

我在我的网站上有两个页面,其中填充了来自数据库的内容,还有用户输入的字段(不要问!)。这些页面还包含一个带有嵌套数据列表的ListView。这些页面上有一些按钮,单击这些按钮可以获取页面的html内容,将其写入HtmlTextWriter,然后获取文本并将其发送到电子邮件中

我需要做的是将html源中的任何文本框/下拉列表替换为字符串文本等价物,然后再放入电子邮件

到目前为止,我的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
到目前为止,我的想法是正确的。手动将任何文本框设置为Visible=false,然后用相应的文本框值填充文本控件,这相当混乱和乏味。注意,我必须去掉输入控件,否则电子邮件的html需要用一个表单元素包装,我真的不想这样做


有没有更好的方法来实现这一切,我想也许用xml文件中定义的页面内容进行一些.Net1.1样式的xslt转换可能是更好的方法,但我不确定这是否能满足我当前使用嵌套数据列表的ListView的需求。

我发现您所描述的内容有很多开销。你的电子邮件模板保持不变吗?如果是这样的话,为什么不简单地用HTML3代码创建一个简单的html模板呢。然后只需从磁盘读取此文件,并用动态内容替换特定的文件(即########)。通过这种方式,您可以完全控制通过电子邮件发送的html,并且可以控制用户输入的内容

这也将限制使html与电子邮件客户端兼容的工作量

澄清:在前面的建议中,我建议将UI实现和电子邮件实现区分开来,这反过来又允许以更大的灵活性撰写电子邮件。不用

mailableContent.RenderControl(htmlWriter);
这还允许您根据自己的规范组合列表视图的内容。

两个想法:

  • 使用正则表达式将文本框和下拉列表的html输出替换为纯文本。(很棘手,查找
    内容很复杂

  • 做我所做的:

    • 创建一个接口,例如
      IPlainTextable
    • 使接口强制一个名为
      PlainTextMode
      的布尔属性(默认设置为false)
    • 使用您自己的控件扩展TextBox和DropDownList,这些控件实现
      IPlainTextable
    • 在扩展网络控件的“渲染”部分,如果
      PlainTextMode
      为true,则渲染出纯文本值。例如,对于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;
    }
    
    公共静态列表FindControlSoftType(控件ctlRoot)
    {
    列表控件查找=新列表();
    if(typeof(T).IsInstanceOfType(ctlRoot))
    controlsFound.Add((T)(object)ctlRoot);
    foreach(ctlRoot.Controls中的控件ctlTemp)
    {
    controlsFound.AddRange(FindControlSoftType(CTLTEM));
    }
    返回控制基金;
    }
    
    所以你可以做一些类似的事情:

    foreach (IPlainTextable ctl in FindControlsOfType<IPlainTextable>(this))
    {
        ctl.PlainTextMode = true;
    }
    
    foreach(FindControlsOfType中的IPlainTextable ctl(this))
    {
    ctl.PlainTextMode=true;
    }
    

    然后再对字符串进行渲染…

    谢谢你的建议,但是这如何满足ListView/DataList的要求呢?我再试试,我不确定我是否理解了这个问题。