Internet Classes

The FCL鈥檚 System.Net namespace includes classes for performing Internet-related tasks such as submitting HTTP requests to Web servers and resolving names using the Domain Name System (DNS). The daughter namespace System.Net.Sockets contains classes for communicating with other machines using TCP/IP sockets. Together, these namespaces provide the foundation for the FCL鈥檚 Internet programming support. Other namespaces, such as System.Web and System.Web.Mail, contribute classes of their own to make the .NET Framework a first-rate tool for writing Internet-enabled applications.

Two of the most useful classes in the System.Net namespace are WebRequest and WebResponse, which are abstract base classes that serve as templates for object-oriented wrappers placed around HTTP and other Internet protocols. System.Net includes a pair of WebRequest/WebResponse derivatives named HttpWebRequest and HttpWebResponse that make it easy for managed applications to fetch Web pages and other resources available through HTTP. Learning about these classes is a great starting point for exploring the Internet programming support featured in the FCL.

HttpWebRequest and HttpWebResponse

HttpWebRequest and HttpWebResponse reduce the otherwise complex task of submitting HTTP requests to Web servers and capturing the responses to a few simple lines of code. To submit a request, use the WebRequest class鈥檚 static Create method to create a request and then call GetResponse on the resulting HttpWebRequest object:

WebRequest聽request聽=聽WebRequest.Create聽("http://www.wintellect.com");
WebResponse聽response聽=聽request.GetResponse聽();

GetResponse returns an HttpWebResponse object encapsulating the response. Calling GetResponseStream on HttpWebResponse returns a Stream object that you can wrap a reader around to read the response. The following code echoes the text of the response to a console window:

StreamReader聽reader聽=聽new聽StreamReader聽(response.GetResponseStream聽());
for聽(string聽line聽=聽reader.ReadLine聽();聽line聽!=聽null;
聽聽聽聽line聽=聽reader.ReadLine聽())
聽聽聽聽Console.WriteLine聽(line);
reader.Close聽();

It鈥檚 that simple. HttpWebRequest also contains methods named BeginGetResponse and EndGetResponse that you can use to submit asynchronous Web requests, which might be useful if you don鈥檛 want to wait around for large amounts of data to come back through a slow dial-up connection.

The LinkList application in Figure 3-5 uses the WebRequest, WebResponse, and Regex classses to list a Web page鈥檚 hyperlinks. Its input is the URL of a Web page; its output is a list of all the URLs accompanying Hrefs in the Web page. Fetching the Web page is easy thanks to WebRequest.GetResponse. Regex.Match simplifies the task of parsing the Hrefs out of the response. To see LinkList in action, as shown in Figure 3-6, compile it and type linklist followed by a URL at the command prompt:

linklist聽http://www.wintellect.com

LinkList also demonstrates that StreamReader objects can read from any kind of stream, not just file streams. Specifically, it uses a StreamReader to read the contents of the stream returned by WebResponse鈥檚 GetResponseStream method. This is abstraction at its finest and is the primary reason that the FCL鈥檚 architects decided to use readers and writers to abstract access to streams.

LinkList.cs
using聽System;
using聽System.IO;
using聽System.Net;
using聽System.Text.RegularExpressions;

class聽MyApp
{
聽聽聽聽static聽void聽Main聽(string[]聽args)
聽聽聽聽{
聽聽聽聽聽聽聽聽if聽(args.Length聽==聽0)聽{
聽聽聽聽聽聽聽聽聽聽聽聽Console.WriteLine聽("Error:聽Missing聽URL");
聽聽聽聽聽聽聽聽聽聽聽聽return;
聽聽聽聽聽聽聽聽}

聽聽聽聽聽聽聽聽StreamReader聽reader聽=聽null;

聽聽聽聽聽聽聽聽try聽{
聽聽聽聽聽聽聽聽聽聽聽聽WebRequest聽request聽=聽WebRequest.Create聽(args[0]);
聽聽聽聽聽聽聽聽聽聽聽聽WebResponse聽response聽=聽request.GetResponse聽();
聽聽聽聽聽聽聽聽聽聽聽聽reader聽=聽new聽StreamReader聽(response.GetResponseStream聽());
聽聽聽聽聽聽聽聽聽聽聽聽string聽content聽=聽reader.ReadToEnd聽();

聽聽聽聽聽聽聽聽聽聽聽聽Regex聽regex聽=聽new聽Regex聽("href\\s*=\\s*\"([^\"]*)\"",
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽RegexOptions.IgnoreCase);

聽聽聽聽聽聽聽聽聽聽聽聽MatchCollection聽matches聽=聽regex.Matches聽(content);
聽聽聽聽聽聽聽聽聽聽聽聽foreach聽(Match聽match聽in聽matches)
Figure 3-5
LinkList source code.
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽Console.WriteLine聽(match.Groups[1]);
聽聽聽聽聽聽聽聽}
聽聽聽聽聽聽聽聽catch聽(Exception聽e)聽{
聽聽聽聽聽聽聽聽聽聽聽聽Console.WriteLine聽(e.Message);
聽聽聽聽聽聽聽聽}
聽聽聽聽聽聽聽聽finally聽{
聽聽聽聽聽聽聽聽聽聽聽聽if聽(reader聽!=聽null)
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽reader.Close聽();
聽聽聽聽聽聽聽聽}
聽聽聽聽}
}
Figure 3-6
LinkList output.
The System.Web.Mail Namespace

Want to send e-mail from a .NET Framework application? You could do it the hard way by using sockets to establish a connection to a mail server and then transmit a mail message using Simple Mail Transfer Protocol (SMTP). Or you could do it the easy way and rely on classes in the System.Web.Mail namespace. System.Web.Mail provides a simple managed interface to SMTP. The core classes are MailMessage, which represents e-mail messages; MailAttachment, which represents attachments; and SmtpMail, which places a friendly wrapper around the host system鈥檚 SMTP mail service.

Here鈥檚 how easy it is to send e-mail from a managed application:

using聽System.Web.Mail;
聽聽.
聽聽.
聽聽.
MailMessage聽message聽=聽new聽MailMessage聽();
message.From聽= "webmaster@wintellect.com";
message.To聽= "Everyone@wintellect.com";
message.Subject聽= "Scheduled聽Power聽Outage";
message.Body聽= "Our聽servers聽will聽be聽down聽tonight.";
SmtpMail.SmtpServer聽=聽"localhost";
SmtpMail.Send聽(message);

Having the capability to send e-mail programmatically can come in handy in countless ways. For example, you might want to send e-mail confirmations to customers who purchase merchandise from your Web site, or you might write your own software to transmit electronic newsletters to clients. Whatever your motivation, it doesn鈥檛 get much easier than this.

Figure 3-7 contains the source code for a simple e-mail client named SendMail, built around the MailMessage and SmtpMail classes. To spice things up just a bit, and to serve as a preview of things to come, SendMail isn鈥檛 a console application鈥攊t鈥檚 a Web application. Specifically, it鈥檚 an ASP.NET Web form. (See Figure 3-8.) Clicking the Send Mail button activates the OnSend method, which composes an e-mail message from the user鈥檚 input and sends it to the recipient. To run the application, copy SendMail.aspx to the \Inetpub\wwwroot directory of a PC that has ASP.NET and Internet Information Services installed on it. Then open a browser and type http://localhost/sendmail.aspx in the address bar. Once the Web form appears, fill in the fields and click the Send Mail button to send an e-mail message.

Some machines require a bit of reconfiguring to allow ASP.NET applications to send mail. If SendMail.aspx throws an exception when you click the Send Mail button, here鈥檚 what to do. First make sure your machine鈥檚 SMTP service is running. You can do that in the IIS configuration manager or in the Services Control Panel applet. Second, make sure the SMTP service is configured to allow relaying from localhost. To do that, open the IIS configuration manager (you鈥檒l find it in Administrative Tools), right-click Default SMTP Virtual Server, select Properties, click the Access tab, click the Relay button, select Only The List Below, and use the Add button to add 127.0.0.1 to the list of computers allowed to relay.

SendMail.aspx
<%@聽Import聽Namespace="System.Web.Mail" %>

<html>
聽聽<body>
聽聽聽聽<h1>Simple聽SMTP聽E-Mail聽Client</h1>
聽聽聽聽<form聽runat="server">
聽聽聽聽聽聽<hr>
聽聽聽聽聽聽<table聽cellspacing="8">
聽聽聽聽聽聽聽聽<tr>
聽聽聽聽聽聽聽聽聽聽<td聽align="right" valign="bottom">From:</td>
聽聽聽聽聽聽聽聽聽聽<td><asp:TextBox聽ID="Sender" RunAt="server" /></td>
聽聽聽聽聽聽聽聽</tr>
Figure 3-7
A Web-based e-mail client.
聽聽聽聽聽聽聽聽<tr>
聽聽聽聽聽聽聽聽聽聽<td聽align="right" valign="bottom">To:</td>
聽聽聽聽聽聽聽聽聽聽<td><asp:TextBox聽ID="Receiver" RunAt="server" /></td>
聽聽聽聽聽聽聽聽</tr>
聽聽聽聽聽聽聽聽<tr>
聽聽聽聽聽聽聽聽聽聽<td聽align="right" valign="bottom">Subject:</td>
聽聽聽聽聽聽聽聽聽聽<td><asp:TextBox聽ID="Subject" RunAt="server" /></td>
聽聽聽聽聽聽聽聽</tr>
聽聽聽聽聽聽聽聽<tr>
聽聽聽聽聽聽聽聽聽聽<td聽align="right" valign="top">Message:</td>
聽聽聽聽聽聽聽聽聽聽<td><asp:TextBox聽ID="Body" TextMode="MultiLine" Rows="5"
聽聽聽聽聽聽聽聽聽聽聽聽Columns="40" RunAt="server" /></td>
聽聽聽聽聽聽聽聽</tr>
聽聽聽聽聽聽</table>
聽聽聽聽聽聽<hr>
聽聽聽聽聽聽<asp:Button聽Text="Send聽Mail" OnClick="OnSend" RunAt="server" />
聽聽聽聽</form>
聽聽</body>
</html>

<script聽language="C#" runat="server">
聽聽void聽OnSend聽(Object聽sender,聽EventArgs聽e)
聽聽{
聽聽聽聽聽聽MailMessage聽message聽=聽new聽MailMessage聽();
聽聽聽聽聽聽message.From聽=聽Sender.Text;
聽聽聽聽聽聽message.To聽=聽Receiver.Text;
聽聽聽聽聽聽message.Subject聽=聽Subject.Text;
聽聽聽聽聽聽message.Body聽=聽Body.Text;
聽聽聽聽聽聽SmtpMail.SmtpServer聽=聽"localhost";
聽聽聽聽聽聽SmtpMail.Send聽(message);
聽聽}
</script>
Figure 3-8
The SendMail application.