As part of using Membership controls in ASP.Net, one thing lot of people do
as part of user creation is send some sort of email to the new user when they register. This email
could be some welcome email or email that send the user their password etc. Good news is that
CreateUserWizard control takes care of most of the email functionality for you. Here
is what you need to make it all work.
How does it work?
CreateUserWizard control sends an email to the newly registered when the new user
has been created. SendEmail event is fired after CreatedUser event has been
successfully fired and handled. Interestingly, CreateUserWizard sends this email using
method SendPasswordMail. It seems this email feature was designed for sending
passwords to user when password is automatically generated. But this does not mean that it is
only going to be called when certain password option is chosen.
MailDefinition is the key
CreateUserWizard control does not try to send email all the time. It looks for
MainDefinition template to be set in the control. If you do not definie
MailDefinition template, control will not send the email. So what you need to do is
fill this template inside your control container. Here is sample implementation from my sample
code.
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:CreateUserWizard ID="RegisterUser"
runat="server" EnableViewState="false"
OnCreatedUser="RegisterUser_CreatedUser"
OnCreatingUser="RegisterUser_CreatingUser"
BorderStyle="Dotted"
OnSendingMail="RegisterUser_SendingEmail"
OnSendMailError="RegisterUser_SendingEmailError">
<LayoutTemplate>
<asp:PlaceHolder ID="wizardStepPlaceholder" runat="server"></asp:PlaceHolder>
<asp:PlaceHolder ID="navigationPlaceholder" runat="server"></asp:PlaceHolder>
</LayoutTemplate>
<MailDefinition
From="xyz@mymail.com"
IsBodyHtml="true"
Priority="Low"
BodyFileName="~/WelcomeEmail.htm"
Subject="Welcome to Project Helpers from ByteBlocks.com">
<EmbeddedObjects>
<asp:EmbeddedMailObject Name="LogoImage" Path="~/Images/ByteBlocksLogo.png" />
</EmbeddedObjects>
</MailDefinition>
</asp:CreateUserWizard>
As you can see, MailDefinition template allows you to configure email parameters. You
do not have to hard code some string as body of your email. It will actually become problem when
you have long HTML content to be sent in email body. You can put content of your email in external file
and then set the path to that file in BodyFileName attribute of MainDefinition.
You can put some token or markers inside that body to replace them with appropriate values at run time. More about it
little later. So remember that MailDefinition is key to sending email as part of
CreateUserWizard control.
Customize email content and attachment
Some time you want to send welcome email to new users with some documents and also want to
have some logo image inside the email body. Well, this all can be handled by using a standard format
that the control provided. You will make use of EmbeddedObjects section of
MailDefinition template. This is where you can include all the external objects or file
paths. Make sure that you have unique names for these objects.
-
To include images inside email body, use the following syntax in HTML email body content.
<img src="cid:LogoImage" alt="ByteBlocks Project Helpers" />
<h2>Welcome To ByteBlocks Project Helper</h2>
This is part of HTML file that I use for email body. The key to this is src=cid:uniqueid part.
This uniqueid is the name of the object that you added in EmbeddedObjects section. You
can see from the markup that I showed earlier that I have included my logo image inside
EmbeddedObjects section.
-
If you need to attach some documents, then include them in EmbeddedObjects section.
Following screenshot shows sample of email that get sent from my application. You can see that at the top of
the email is sample logo image as well.
Configure SMTP Server for CreateUserWizard Email
This is one of the most asked question to me. Where do I set SMTP server settings for emails from
CreateUserWizard?. When SendEmail event is fired, you get
MailMessageEventArgs object as parameter of event handler. This object only provides
you access to email message only. It does not provide a way to configure SMTP settings for outgoing
email. Then how do you set it?
See the following call stack when CreateUserWizard control is trying to send the email
out.
System.Net.Mail.SmtpClient.Send(MailMessage message)
System.Web.UI.WebControls.LoginUtil.SendPasswordMail(String email, String userName,
String password, MailDefinition
Now if you look at constructor of SmtpClient, it initializes the settings of email
transport from mailSettings section of web.config. That means the place
to configure your SMTP server is in web.config file. Add mailSettings section in
system.net section of web.config value. Following snippet shows
you an example from my site.
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="xyz@myisp.com">
<network host="localhost" />
</smtp>
</mailSettings>
</system.net>
You can provide the values as per your server settings. If you are just testing using your local machine
as email relay then you do not have to specify these settings. SmtpClient by default will
use local machine.
Important things
There are few things that you will need to pay attention to when setting up this MailDefinition
template and changing settings for MailMessage.
-
Make sure that you have specified an email address in From section. This does not have
to be a valid emails address. You can simply put something like noreply@mydomain.com. But do not leave
it empty.
-
If your process does not require the users to provide their email address but you still want to send some
email for record keeping then you can add a placeholder email to To collection. You
can not leave To collection empty. Otherwise SmtpClient object will throw exception at you.
protected void RegisterUser_SendingEmail(object sender, MailMessageEventArgs e)
{
var sendTo = RegisterUser.Email;
if (string.IsNullOrEmpty(sendTo))
{
sendTo = "foo@bar.com";
e.Message.To.Add(sendTo);
}
}
Do provide an event handler for SendEmailError. If there is some error or
exception thrown during outoging email process, you can look at the error message. Handle this error gracefully and
then set Handled properly.
protected void RegisterUser_SendingEmailError(object sender, SendMailErrorEventArgs e)
{
System.Diagnostics.Trace.WriteLine(e.Exception.Message);
e.Handled = true;
}
If you do not handle this error, then it will get propagated to the top as unhandled exception and depending
on your CustomError settings, users may see ugly yellow screen with full stack trace and all.