Introduction
This article describes a Web control, FormMailer
, which when placed on an ASPX form, transforms it into a user feedback form that's emailed to any specified email address. FormMailer
has the following features:
- Adds the email capabilities to the form just by virtue of being placed on it.
- Any mail headers can be added to the email sent by adding special tags to the body of the
FormMailer
user control tag.
- Displays a submit button or link.
- Once the button is clicked,
FormMailer
gathers the values entered into the form's TextBox
ASP controls, composes an email message and mails it to an email address specified as an attribute.
- After the email is sent, the form is redisplayed with a confirmation message informing the user that the form was submitted.
FormMailer
is a highly reusable and easy to use control because of its ability to automatically gather the information it needs from the form itself and turn it into an "emailable" form.
Background
The FormMailer
control introduced here is an example of a self configuring object. Aside from discussing the specifics of FormMailer
I would also like to say something about self configuration. I was first introduced to the concept of self configuring objects during my days as a Macromedia Director programmer, but ASP.NET is an excellent technology to take advantage of this idea. A self configuring object, be it a GUI or some non-visual component, is an object that, ideally, knows how to think and what to do no matter what environment you plop it into. In some sense, self configuration is similar to the object oriented concept of polymorphism, which says that things can have a different meaning, usage, or behavior, depending upon the context in which they are used. Polymorphism typically manifests itself as some OO language feature, such as a function that takes arguments of different types.
Self configuring objects do not specifically depend on any OO language feature, but are simply capable of looking at the context into which they are put and behave accordingly. The main philosophy of building a self configuring object is that any knowledge that can be derived by the given environment should be derived from that environment and not duplicated from somewhere else, such as passed parameters. For a specific example of this within FormMailer
, take a look at the Points of Interest section.
Using the code
After you've included FormMailer.cs somewhere in your project, create a Web form with the text box fields you'd like to be emailed. The fields should be the form's top level controls, that is, not nested within any other server side tag except for the form. Register the FormMailer
control with a tag such as this one:
<%@ Register TagPrefix="uc" NameSpace="YWLib.Utility.Controls.FormProcessing" Assembly="FormMailerDemo" %>
.
Finally, place the FormMailer
tag on the form. The following code block is a sample FormMailer
tag. The FormMailer
tag displays a submit button, so it should be placed accordingly. An example of a full form page can be found in the code download for this article.
<uc:FormMailer id="FormMailer" runat="server"
ControlToShowOnSuccess="SuccessPanel"
SmtpServer="localhost" ControlToHideOnSuccess="InstructionsPanel">
<asp:Button id="SubmitControl" runat="server" text="Send Message">
</asp:Button>
<MailTemplate>
---#Name#---
#Text#
</MailTemplate>
<MailHeader Name="From" Text="formmailer@yourdomain.com" />
<MailHeader Name="To" Text="webmaster@yourdomain.com" />
</uc:FormMailer>
As you can see in the code above, the FormMailer
tag contains a few properties (tag attributes), an embedded asp:Button
tag, a MailTemplate
tag, and some MailHeader
tags.
The asp:Button
tag, is just a regular ASP button control, but it exists within the FormMailer
. Upon loading, the FormMailer
control looks for an ASP button provided within it's body text, and automatically binds its click event to a function that submits and mails the form. In place of the asp:Button
, the FormMailer
control also accepts an asp:LinkButton
or an asp:ImageButton
.
The
MailTemplate
tag is used to format each of the emailed fields.
FormMailer
substitutes the ID of a field into the #Name# tag and the value into the #Text# tag. For example, if a form contains these two text fields,
<asp:textbox id="Name" runat="server"></asp:textbox>
and
<asp:textbox id="Email" runat="server"></asp:textbox>
,
The emailed message sent by the sample FormMailer
above, will look like this:
---Name---
John G
---Email---
johng@somedomain.com
Note that unlike in HTML, white spaces within the MailTemplate
tag do affect the formatting. Also, the MailTemplate
tag is optional, and FormMailer
does use default formatting if it's missing.
The MailHeader
tags allow you to add any mail header to the email sent. Just put the header's name into the Name
attribute, and the header's value into the Text
attribute. You can also assign the value of a header from a TextBox
control by setting the MailHeader
's TextFromTextBox
attribute to the ID of the control. If both Text
and TextFromTextBox
attributes are specified, then Text
acts as a default value if the text box is empty. The most important header is the To header, which specifies the recipient of the form's email. As a convenience, the headers Subject and Reply-To are automatically added to the email from text boxes whose IDs end with "Subject" and "EmailAddress" (case insensitive), respectively. The content of the subject text box is omitted from the body of the email, and therefore appears only as the email's subject
The following are the FormMailer
control properties:
ControlToShowOnSuccess
- The control whose ID matches this property will be hidden when the form is loaded and shown after the form is emailed. The control must not be nested within any other control or it won't be found by FormMailer
.
ControlToHideOnSuccess
- Similar to ControlToShowOnSuccess
, except that the control is hidden after the email is sent.
DontMailPrefix
- If this property is set, FormMailer
will not email the form's TextBox
controls whose ID strings start with the value of this property.
DisableFieldsAfterSend
- If set to true
, the form's fields and submit button are disabled after the email is sent. This is useful in conjunction with a label control used with ControlToShowOnSuccess
that states something like "Thanks for emailing us. Here is the information you sent." The user then sees the same form, but with uneditable fields. The default of this property is true
.
SmtpServer
- Set this property to the name of your SMTP server. The default is "localhost".
FormMailer
also includes an event called MailSent
that is fired after the email is sent. Handle this event if you'd like to execute code after the email is sent, e.g. redirect to a different page.
Finally, FormMailer
only supports the mailing of the content of TextBox
controls placed on the form and the rest are ignored, but it can be easily extended to process other types of controls.
Points of Interest
Let's look at a portion of the heart of FormMailer
, the function that's responsible for actually mailing the form. The rest of the code also includes many interesting points but they mostly belong to the general category of building custom controls. Perhaps I'll elaborate on that portion of the code sometime in the future.
This function is named MailTheForm()
, and it's called directly from the button's click event. The full listing is in the downloadable code of course.
The first task MailTheForm
performs is finding the page's HtmlForm
control, and the controls it wraps.
HtmlForm formControl = GetFormControl(Page);
ControlCollection controlsToMail = formControl.Controls;
It might seem simple, but this is an important part of following the self configuration philosophy. FormMailer
could have just as well been designed to accept some sort of a list of IDs of controls to be emailed. But instead, FormMailer
finds the controls it needs to take care of on its own.
GetFormControl()
is a helper function that finds the page's HtmlForm
control. It contains a simple loop:
foreach (Control control in page.Controls)
{
if (control is HtmlForm)
{
return (HtmlForm)control;
}
}
return null;
MailTheForm()
then loops through all the form controls, and processes the text boxes like so:
if (control is TextBox)
{
TextBox textBox = (TextBox)control;
if (textBox.Text.Length > 0)
{
if (textBox.ID.ToLower().EndsWith("subject"))
{
subject = textBox.Text;
}
else if (textBox.ID.ToLower().EndsWith("emailaddress"))
{
replyTo = textBox.Text;
messageText.Append(mailTemplate.getTemplateText(textBox.ID,
textBox.Text));
}
else
{
messageText.Append(mailTemplate.getTemplateText(textBox.ID,
textBox.Text));
}
}
}
Notice that the first if
, excludes all controls that are not text boxes. To augment FormMailer
with the ability to process other types of controls, just include them in else if
clauses here. textMessage
is a StringBuilder
that is used to form the email body string. mailTemplate
is a MailTemplate
type object. The MailTemplate
class is responsible for formatting the text that's appended to the email body.
Conclusion
FormMailer
is designed to mail-enable a form with a minimal amount of configuration, and is a good example of the reusability and compartmentalization power of ASP.NET.
This article mostly described the use of the FormMailer
. For readers who would like to dive into code, I tried to include a reasonable amount of comments within the source.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.