Asp.Net page email content

I have two pages on my site that are filled with content from a database, as well as user-entered fields (don't ask!). Pages also contain a ListView with a nested DataList. These pages have buttons that, when clicked, grab the content of the html of the page, write it to the HtmlTextWriter, then get the text and put it in the email.

What I need to do is replace any TextBox / DropDownLists in the html source with string literal equivalents before putting it into the post.

My aspx code so far looks something like this:

<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>

      

and the codebehind looks something like this:

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

      

My ideas so far are to 1. manually set any textboxes to Visible = false and then populate the literal controls with the appropriate textbox values, which are pretty messy and tedious. Note. I need to delimit the input elements, otherwise the html for the email has to be wrapped with a form element, which I really don't want to do.

Is there a better way to do all of this, I think maybe do some. Net1.1. Style xslt transforms with page content defined in xml files might be the best way to approach this, but I'm not sure if this will handle my requirement when I am currently using a ListView with a nested DataList.

+2


source to share


2 answers


I find what you describe to have a lot of overhead. Is your email template the same? if so why not just create a simple html template with html 3 code. Then just read that file from disk and replace specific labels (i.e. ## Name ##) with dynamic content. This way, you have complete control over the html sent by email and you can control which users enter.

it would also limit the work to make the html compatible with email clients.

Clarification . In a previous sentence, I suggest that the interface implementation and email implementation are clear, which in turn allows for more flexibility in packaging the email. Without use



mailableContent.RenderControl(htmlWriter);

      

it also allows you to compose the contents of the ListView .

+1


source


A couple of ideas:

  • Use RegEx to replace the html output of text boxes and dropdownlists with plain text. (Tricky, with the complication of finding material <option selected="selected">

    .

  • Do what I do:

    • Create an interface for example. IPlainTextable

    • Make the interface enforce a boolean property called PlainTextMode

      (set to false by default)
    • Extend TextBox and DropDownList with native controls that implement IPlainTextable

    • In the Render section of extended webcontrols, output the plaintext value if PlainTextMode

      true. for example for your TextBox subclass

      protected override void Render(HtmlTextWriter writer)
      {
         if (PlainTextMode)
            writer.WriteLine(this.Text);
         else
            base.Render(writer);
      }
      
            

    • Before rendering your page, complete all controls IPlainTextable

      and set PlainTextMode

      to true

      .

I wrote a great method for iterating through a nested set:

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

      



So, you would just do something like:

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

      

and then do your render after the line ...

+1


source







All Articles