Software Development

Get started coding C# in ASP.NET

To truly tap into the power of ASP.NET, you must dig below the surface and realize that everything--everything--is an object. This simple walkthrough illustrates basics of Namespace, class, and some of the platform's other powerful features.

Many Web developers embraced Microsoft's Active Server Page (ASP) technology and have used it widely to build Web applications. Now ASP.NET is here to provide a new generation of dynamic Web sites. ASP.NET, available through the .NET SDK, provides an object-oriented method for creating and interacting with Web pages. Those of us familiar with ASP will find a lot of similarities in ASP.NET, but those likenesses are primarily on the surface. A deeper investigation reveals the power of ASP.NET.

To really excel with ASP.NET and the rest of .NET, it is important to remember that everything is an object--everything. Also, ASP.NET pages are compiled initially at runtime, so the first load of a page may prove slow, but all additional loads will be very quick. Finally, since the pages are compiled, the ASP.NET specific code for items such as controls are automatically converted to vanilla HTML.

In the first article in this series, we discussed how to set up a .NET server. Now, let’s look at some coding basics.

The return of "Hello World"
Just about every programming language tutorial starts with the inevitable "Hello World" example, and this article is no exception. Let's take a look at a C# version of "Hello World":
<%@ Page Language="C#"%>
<title>Hello World!</title>
   <% for (int i=0; i <6; i++) { %>
      <font size="<%=i%>"> I don't want the world, I just want your half </font> <br>
   <% }
   Response.Write("<p><cite>They Might Be Giants - Ana Ng</cite>");

Let's dissect this code line by line.
<%@ Page Language="C#">

The initial line, the page directive, notifies the common language runtime (CLR) of any page-specific information that is required. In this instance, it defines the scripting language for the page as C#. Directives are also used for specifying necessary information that may be contained in Namespaces or controls.

To include code within the page, note the commonplace <% notation. ASP.NET supports two methods of utilizing code within the page. Code blocks, such as the one above, are one method. Using a <script runat=server> block is the other.
<% for (int i=0; i <6; i++) { %>
   <font size="<%=i%>"> I don't want the world, I just want your half </font> <br>
   <% }

In this example, when we look at the code only, we have a simple for loop that iterates from 0 to 5 and terminates. The code processed by the loop is enclosed within brackets. Since the C# language style is very similar to C and Java, the syntax is very curt and doesn't include terms such as next. <%=i%> is an evaluative statement. Use it whenever a variable's value will be directly embedded within HTML. In this case, the statement evaluates i, the iterator of the for loop.
Response.Write("<p><cite>They Might Be Giants - Ana Ng</cite>");

Response.Write is used to write output from the script to the page. In this case, it is simply writing the HTML included within the quotes. The ASP.NET code is encased within the rendering blocks <% and %>. These need to be used as a wrapper around any code that is included within an HTML block.

You can see the output of our "Hello World" script in Figure A.

Figure A
Our first .NET coding example iterates through our text six times, incrementing the size of the font on each iteration.

Adding class and using Namespaces
For many developers, Namespaces, both in concept and in use, may end up being a headache at first. For those familiar with Java, they are akin to class libraries. For those with a VB background, they are similar to References. Namespaces are used to organize libraries and assist in using objects and object identifiers properly.

At first, you will find yourself primarily using the Namespaces included within the framework, as they contain most of the framework's functionality. It is also possible to create your own Namespaces, which is particularly useful in more advanced applications. In a normal ASP.NET application, Namespaces are referenced like this:
<%@ Import Namespace="System.IO " %>

The Import directive specifies that the Namespace is utilized. Use the following code to work with Namespaces within C# applications.
Using System.IO;

The framework contains a large collection of Namespaces and their respective base types. You should examine these Namespaces in depth. If you have Visual Studio, .NET full descriptions are contained within the help system, including class descriptions, methods, properties, and attributes. Namespaces are also covered on the MSDN Web site.

The wild world of Web forms
With ASP.NET, the ability to develop highly reusable functional forms becomes a reality. We can't illustrate all of the improvements in a simple example, but this should get you started. We'll alter our "Hello World" example to show some simple forms development:
<%@ Page Language="C#"%>
<title>Hello World!</title>
<form action="HelloWorld2.aspx">
<asp:TextBox id="sentence" maxlength=100 width=200px runat=server />
<input runat="server" type=submit value="Submit" ID="submit" NAME="submit"><br>

   <% if (Request.QueryString["submit"] != null) {
      for (int i=0; i <6; i++) { %>
      <font size="<%=i%>"> <%=Request.QueryString["sentence"]%></font> <br>
      <% }

You will immediately notice that the HTML attribute <input type=text> is not used and is replaced with the <asp:textbox> control. ASP.NET automates forms manipulation, providing that you use the ASP.NET controls. Using the TextBox control, we write server-side code to perform live client-side validation and also directly integrate into other .NET objects. Another thing to remember: We no longer need <input type=hidden> tags to store our data. All information is retained through the round-trips to the server.

We didn't specify the form method, so the application defaults to GET and appends the form data as a query string. That's why we use the Request.QueryString method to obtain the values of the form elements. As in the first example, the string is repeated six times in greater and greater font sizes.

Controlling those controls
The Web Forms controls collection provides numerous means of handling form data more simply than was previously available. All of the controls are contained in the following two Namespaces: System.Web.UI.HtmlControls and System.Web.UI.WebControls. HTML server controls (HtmlControls) have an object model that maps very closely to the HTML elements they render. Web server controls (WebControls) are more abstract in that their object model does not necessarily reflect HTML syntax but relates to the control itself. Finally, there are custom-built controls, which are outside of the scope of this article.

So what can we do with these controls? Well, first off, we can style them:
<button style="font: 8pt verdana;background-color:lightgreen;border-color:black;width:100" runat="server">Click me!</button>

You can see the results in Figure B.

Figure B
This button is how the preceding code will render in a browser. 

Next we can use them to validate input in our forms:
Email Address: <asp:TextBox id=email width=200px maxlength=60 runat="server" /><br>

<asp:RequiredFieldValidator id="emailReqVal" ControlToValidate="email"
ErrorMessage="Email. " Display="Dynamic" runat=server>*

<asp:RegularExpressionValidator id="emailRegexVal" ControlToValidate="email"
ErrorMessage="Email. " Display="Static"
ValidationExpression="^[w-]+@[w-]+.(com|net|org|edu|mil)$" runat=server>
Not a valid e-mail address. Must follow email@host.domain.

On initial inspection, this seems like far more work than HTML's <input type=text>, and on the surface, it is. However, there is a significantly greater amount of functionality here. The initial <asp:textbox> is the form input and appears similar to a standard form input. The RequiredFieldValidator ensures that the text box is not left empty as the user fills out the form. Setting the Display attribute to Dynamic causes the validation to occur on the client side.

The RegularExpressionValidator operates on the server side and is invoked only when the Submit button is clicked, as indicated by the Display="Static" attribute. In this particular example, the validator is a regular expression to ensure that the e-mail address is correctly formed.

You can capture user events with a control, redefine controls, and create your own custom user controls.

Server-side data access
While the .NET version of ActiveX Data Objects (ADO) may look fairly similar to its predecessor, there are many more features. Gone is the RecordSet, which has been replaced by a DataSet. While they sound the same, they work much differently. DataSet is, in essence, a miniature representation of a database, containing returned data as well as the schema of the data source, letting the code integrate with the database. In addition to DataSet, a DataReader has been implemented. The DataReader is a forward-only database connection used for rapidly returning query results to a Web form. Finally, there are now two different types of ADO connection, based on whether you are connecting to Microsoft's SQL Server or another ADO source.

The connection syntax remains fairly similar to ADO's style, but note that these examples are in C# and are for connecting to a Microsoft SQL database.

For starters, you need to make sure that you are using the proper Namespaces. For connecting to SQL Server use:
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>

Now we need to create the connection object:
SqlConnection myConnection = new

The connection string from earlier ADO strings has changed. Primarily, the user ID and password fields have been replaced by Trusted_Connection=yes. While you can still use the older method, the Trusted_Connection attribute is part of the new security model for .NET.

Now that we've created our connection, we need to generate a DataAdapter and fill our DataSet with the information returned by our query:
SqlDataAdapter myCommand = new SqlDataAdapter("select * from Artists", myConnection);
DataSet ds = new DataSet();
myCommand.Fill(ds, "Artists");

SqlDataAdapter serves as a bridge between the data source and the DataSet. It maintains the data integrity while performing most of the SQL tasks. Once the DataAdapter has performed its job, the DataSet is declared and filled using the Fill method.

One of the really nice improvements to ADO is in updating, inserting, and deleting records. If we had performed some changes to the DataSet from the Artists table, we would simply need to run this update command to commit the changes to the database:

By using the DataSet and XML connection string, manipulation of XML files is equally as simple:
DataSet ds = new DataSet();

FileStream fs = new FileStream(Server.MapPath("schemadata.xml"),FileMode.Open,FileAccess.Read);
StreamReader reader = new StreamReader(fs);

The XML is opened and read using FileStream and StreamReader. These are part of the System.IO Namespace.