Building a newsletter management service in ASP.NET: Part 2


by Jason Salas, KUAM.COM
February 10, 2003

 

Past editions:

Program a time-coding application to calculate read-times

Building a newsletter management system in ASP.NET with C#: Part 1

A simple document management system in ASP with XML and XSLT

Password-protect your Web work

Error Handling in VBScript

Creating a banner ad rotation system

The Web-safe color palette for developers

Time-saving Windows shortcuts

Analyzing your site's traffic logfiles

Technologies Used:

Level of Difficulty

Download the source code for this project

Hello fellow code warriors!

I hope you’ve downloaded the sample code for Part 1 of this tutorial, because now we’re going to expand on it, and add the missing element – the script that sends your newsletter out!

In this installment of “Dev Dungeon”, we’re going to build a simple application that uses an ASP.NET WebForm to setup and send out e-mail messages to a series of recipients. Many people send bulk messages by inserting multiple e-mail addresses in the “BCC” field of an e-mail program. This is fine, but doesn’t allow for much customization, and tends to be too generic. We’ll expand on the newsletter subscription system we built in Part 1 of our tutorial, by developing a class that can be reused and extended in other applications.

You’ll recall that in Part 1, we used the direct inline coding method, embedding our server-side code directly within the .ASPX file, within <SCRIPT> blocks. This clearly separated the code from the content, letting us easily write our programming logic, and then define the user interface in HTML and ASP.NET Web server controls at the page-level.

Now, we’re going to take this a step further and really separate code from content, using ASP.NET’s code-behind approach to development. Code-behind preaches complete isolation of programming code from the user interface elements of a WebForm, making for a better development environment.

This may seem like overkill for individual developers working on a single-function task (and if such is the case it usually is), but using code-behind perfect suited for developing reusable classes that can be incorporated over and over again, spanning multiple projects. It’s also ideal for development teams wherein the programmers, HTML designers, and content editors aren’t always one and the same person.

So, onto the code.

1 using System;
2 using System.Web;
3 using System.Web.UI;
4 using System.Web.UI.WebControls;
5 using System.Data;
6 using System.Data.SqlClient;
7 using System.Web.Mail;
8 
9 namespace techtalkdemos
10 {
11     public class MassMailer : Page
12     {
13         
14         // declare the server controls to be used on the WebForm
15         protected Panel pnlForm;
16         protected Label lblConfirmation;
17         protected TextBox txtFrom;
18         protected TextBox txtSubject;
19         protected TextBox txtBody;
20         protected Button btnSubmit;
21         
22         public void Send_Mail(object sender, EventArgs e)
23         {
24             pnlForm.Visible = false;
25             
26             SqlConnection conn = new SqlConnection("server=localhost;uid=sa;pwd=password;database=Newsletters;");
27             SqlCommand comm = new SqlCommand("SELECT DISTINCT Email FROM BreakingNews",conn);
28             SqlDataReader dr;
29                         
30             MailMessage mailer = new MailMessage();
31             mailer.From = txtFrom.Text.Trim();
32             mailer.Subject = txtSubject.Text.Trim();
33             mailer.Priority = MailPriority.High;
34             mailer.Body = txtBody.Text.Trim();
35             mailer.BodyFormat = MailFormat.Html;
36             mailer.Bcc = "webmaster@kuam.com";
37             
38             try
39             {
40                 conn.Open();
41                 dr = comm.ExecuteReader(CommandBehavior.CloseConnection);
42                 
43                     // loop through the records in the database table and send a message to each of the recipients
44                     while(dr.Read())
45                     {
46                         mailer.To = dr[0].ToString();
47                         SmtpMail.SmtpServer = "localhost";
48                         SmtpMail.Send(mailer);
49                     }
50                     
51                 dr.Close();
52                 
53                 lblConfirmation.Text = "Your message was successfully sent to its recipients!";
54             }
55             catch(SqlException ex)
56             {
57                 Response.Write("A database-related exception occurred!<br>" + ex.ToString());
58             }
59             catch(Exception ex)
60             {
61                 Response.Write("A general exception occurred!<br>" + ex.ToString());
62             }
63             finally
64             {
65                 if(conn.State == ConnectionState.Open)
66                 {
67                     conn.Close();
68                 }
69             }
70         }            
71     }
72 }

Plan your code, code your plan
We start out by creating a blank text file and saving it as InternalMail.cs. This will hold the custom class we’re going to build using C# to hold the functionality for sending our e-mail to our mailing list. At the top of the file, we declare all of the namespaces that contain the classes we’ll need to use to send our newsletter announcement out, with the using keyword. This is similar to Java’s use of the imports statement, or Visual Basic .NET’s use of the Imports statement.

Specifically, we’ll be using Microsoft SQL Server 2000 as the database server, so I’ve declared the System.Data and System.Data.SqlClient namespaces. If you’re using Access, Sybase, Oracle, or some other database platform, you should change the latter namespace to System.Data.OleDb. Since we’ll need access to the .NET Framework’s MailMessage class, we also need to declare the System.Web.Mail namespace.

Moving down into the class definition, notice that with code-behind you explicitly need to have your custom class derive from the Page class, which in turn is inherited from the System.Web.UI namespace. This allows us to place server controls and write content directly onto an .ASPX WebForm. We then declare a series of protected class-level variables in lines 15-20 that constitute the server controls we’re going to reference programmatically in our WebForm.

Next, we define a method to be executed to be wired to the OnClick event of the button server control we just declared. The beginning of the method in lines 24-28 is pretty self-explanatory ADO.NET database connection syntax, so I’ll leave that for you to interpret. Part 1 of this tutorial explains this process in greater detail, so refer to that article if you’re stuck. In lines 30-36, we finally get around to using the aforementioned MailMessage class. The MailMessage class contains several properties for defining and formatting a MIME e-mail message, several of which we set programmatically, consisting of the static information to be included in the message.

The magic of this process is evident in lines 44-49. While inside a try… statement that opens a connection to our database and executes a SqlDataReader object, we use a while… loop to cycle through the records in the database table defined in the SQL statement we laid out when instantiating our SqlCommand object. We use this loop to dynamically assign each record in the Email field in the database table to the To property of the MailMessage object, mailer. We then call the Send method in line 48 to send an e-mail message to that particular e-mail address.

The rest of the code in the Send_Mail method closes up open database connections, and closes off the class and namespace definitions.

The UI
With the programming logic taken care of, let’s now look at the visual elements for the WebForm to be written in the .ASPX file (see Figure 1).


Figure 1: the WebForm's Web server controls render the HTML form elements to the page

First off, we have to tell the ASP.NET page that the server-side code we’re using isn’t in the current file, but in a remote class. We do this with the Inherits and src attributes within the Page declaration, by assigning the namespace.class convention the form uses and the physical location of the class file on disk, respectively.

Using the instance names of the protected variables we declared in our code-behind file we lay out the form in the way we want it to appear. We encapsulate all of the server controls - except the lone Label control - within a Panel server control. We do this so that upon post back, the only visible element will be the Label control, which returns a friendly message to the user, (see Figure 2).

Testing out the WebForm, we see the form we laid out above, and upon submission, see the confirmation message we defined as the Text property for the Label server control. Figure 3 shows the e-mail message that is sent to each user in the database.

<% @ Page Language="C#" Inherits="techtalkdemos.MassMailer" src="InternalMail.cs" Debug="False" Trace="False" EnableSessionState="False" EnableViewState="False" %>

<html>
<head>
<title>Send a mass e-mail using ASP.NET and the MailMessage class</title>
</head>
<body>
<asp:Label id="lblConfirmation" runat="server"/>
<asp:Panel id="pnlForm" runat="server">
<form runat="server">
<h2>Send an e-mail to your mailing list</h2>
<br>
Your e-mail address:
<br>
<asp:TextBox id="txtFrom" runat="server"/>
<br><br>
The subject of your e-mail:
<br>
<asp:TextBox id="txtSubject" runat="server"/>
<br><br>
The body of your e-mail message (HTML tags accepted):
<br>
<asp:TextBox id="txtBody" textmode="Multiline" columns="60" rows="8" runat="server"/>
<br><br>
<asp:Button id="btnSubmit" onclick="Send_Mail" text="Click here to send ==&gt;" runat="server"/>
</form>
</asp:Panel>
</body>
</html>


Expansion

The basic premise of this application is that e-mail is sent to individual Internet users, providing for better newsletters through customization. You could very easily extend your database table and include the user’s name (as we collected in Part 1), and then build this into the design of your custom class and provide custom, personalized greetings when the e-mail arrives. For this same reason, maintenance of the newsletter subscription list is easier. It doesn’t take a lot of code to build in an “unsubscribe” feature that would pass the user’s e-mail address, and optimally, the unique key ID field, to remove a user from receiving any future mailings.

Have fun with this – and happy programming!


Figure 2: successfully sending out the WebForm to recipients


Figure 3: a successful newsletter is sent via MIME e-mail to the recipients listed in your database, one at a time

 

Download the source code for this project

Have fun using this in your own projects!