Cheat Sheet For The Razor Syntax: Object 2

Download as pdf or txt
Download as pdf or txt
You are on page 1of 35

The complete ASP.

NET Tutorial
Welcome to this ASP.NET Tutorial, currently consisting of 38 articles covering all the most important
ASP.NET concepts. This tutorial is primarily for new users of this great technology, and we
recommend you to go through all the chapters, to get the most out of it as possible. While each chapter
can be used without reading the previous chapters, some of them may reference things done in earlier
chapters.

Have a look at the Table of contents to the right, where all the chapters are listed. This tutorial is never
Object 2

done - we will keep adding new stuff to it, so check back regularly. We hope this tutorial helps you to
Object 1

get started with ASP.NET.

Please be aware that this tutorial is for ASP.NET WebForms. If you're looking to learn ASP.NET MVC
instead, we're working on a new tutorial about this, but in the mean time, have a look at this cheat sheet
for the Razor syntax.

Everything here is free, and we hope you like our work. If you do, then all we ask is that you link to
this tutorial on your website, personal blog or anything else where a link is possible. Also, if you see
anything interesting in one of our ad blocks, please click it to help us maintain this tutorial. If you need
any additional help, you can always get help with asp programming. Thank you!

Your first website


You need to select "ASP.NET Web Site", if it's not already selected. You should also name your new
site. This is done by entering a name in the Location box. This text box is probably already filled for
you, with the last part being something like "Website1". You can choose to accept this, as well as the
location of the project, or you can enter a new one, like I did. I have created a folder, "My Websites",
and within this folder, I would like to create the new project with the name of "FirstWebSite". For now,
this is less important, but later on you might wish to gather all your projects in a specific folder.

This tutorial will focus on the C# language. Once again, no knowledge of this is required, so if you
already know another .NET language, you will get to learn some C# with this tutorial as well. Select
C# in the Language dropdown. Now, click the Ok button to create this new website.

VS will create a very basic website for you, consisting only of a Default.aspx file (and it's partner, the
Default.aspx.cs file) and an App_Data folder. I will explain this later, but for now, just accept the fact
that they are there. We will only use the Default.aspx for this first example. Move on to the next
chapter, for the obligatory "Hello, world!" example.

Hello, world!
In almost every programming tutorial you will find the classic "Hello, world!" example, and who am I
to break such a fine tradition? Let me show you how you can say hello to the world from ASP.NET.
Open the Default.aspx (if it's not already opened) by doubleclicking it in the Solution Explorer. It
already contains a bunch of HTML markup, as well as some stuff you probably won't recognize, like
the Page directive in the top, or the runat attribute on the form tag. This will all be explained later, but
for now, we want to see some working code.
First of all, we will add a Label control to the page. A Label control is some what simple, since it's just
used to hold a piece of text. Add the following piece of HTML-looking code somewhere between the
set of <form> tags:

<asp:Label runat="server" id="HelloWorldLabel"></asp:Label>

Secondly, add this script block somewhere on the page, preferably below the Page directive in the top:
<%
HelloWorldLabel.Text = "Hello, world!";
%>

If you haven't worked with ASP.NET before, I'm sure there's a bunch of things that you're wondering
about now, but as I said, this is all about seeing some results right now. To see the page in action, use
Debug -> Start Without Debugging, or simply press F6. Visual Studio will now compile your project,
and launch the page you're working on in your default browser. The page will simply have a piece of
text which says "Hello, world!" - congratulations, you have just created your first ASP.NET website!
Here is the complete listing:
<%
HelloWorldLabel.Text = "Hello, world!";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label runat="server" id="HelloWorldLabel"></asp:Label>
</div>
</form>
</body>
</html>

CodeBehind
While our first example was fine, we unfortunately broke one of the coding principles of ASP.NET: To
separate markup and code. As you noticed, we added a scripting block (using <% %>), where we wrote
a line of C# code to use the label. While this is just fine for a small and simple example like this, we
would soon get a real mess with a bunch of C# code within an even bigger amount of HTML code. If
you throw in some JavaScript and some CSS as well, it will soon become very chaotic to edit. That's
why MS introduced CodeBehind, a technique which allows you to completely separate markup
(HTML, CSS etc.) and code (C#, VB.NET etc.). So let's remove the script block (from <% to %>) and
save the file.

As we talked about earlier, VS added a file called Default.aspx.cs. If you can't see it in the Solution
Explorer, then click the little plus sign left of the Default.aspx file. Open this file. Now, if you haven't
worked with .NET or another non-web programming language before, it might look a bit scary at this
point. It looks nothing like HTML. However, I will try to explain the different parts of the content, and
soon you will hopefully see that CodeBehind is a great tool to get a better overview of your work. Here
is a complete listing of the file as it looks right now:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{

}
}

For now, the top part is rather irrelevant to us. It's a list of namespaces being included with the using
keyword, for usage in the file. Since this is an ASP.NET tutorial and not a dedicated C# tutorial, I won't
explain this in depth. Next, we have the class. Classes are a part of the concept of Object Oriented
programming, which has become very popular, especially with languages like Java and C#. OO is a
very complex subject, which also won't be explained within this tutorial.

The name of this class is "_Default", and the : (colon) tells us that this class inherits from the Page class
in the System.Web.UI namespace. This means that our page can already do a bunch of things, without
any programming, because it inherits methods and properties from another class. All ASP.NET pages
inherits from the Page class, or another class which inherits from the Page class.

Events
ASP.NET is an event-driven way of making web applications. With PHP and Classic ASP, you have
one file, which is executed line after line, from start to end. However, ASP.NET is very different. Here
we have events, which are either activated by the user in one way or another. In the previous example,
we used the Page_Load method. Actually, this is an event, which the Page class calls when the page is
loaded. We will use the same technique in the next example, where we will add a couple of controls to
our simple hello world example. To make it a bit more interesting, we will change the "world" word
with something defined by the user. Have a look at this codelisting, where we add two new controls: A
Button control and a TextBox control.

<form id="form1" runat="server">


<div>
<asp:Label runat="server" id="HelloWorldLabel"></asp:Label>
<br /><br />
<asp:TextBox runat="server" id="TextInput" />
<asp:Button runat="server" id="GreetButton" text="Say Hello!" />
</div>
</form>
As you can see, we now have the 2 new controls added, but they really can't do much at the moment.
You can run the example if you wish to check this out for your self - if you click the button, the page is
simply reloaded. Let's change that, and let's start by doing it the easy way. VS comes with a
WYSIWYG editor, and while I hardly ever use it my self, it does make some things easier, like creating
events.

So, click the Design button in the bottom of VS. Now you will see a visual representation of our page.
We wish to add a Click event to the button, and this is very simply - just doubleclick the GreetButton,
and you will be taken to the CodeBehind file of our page. As you can see, a fine new method has been
added, called GreetButton_Click. If you have a look at the Default.aspx file (you need to go from
Design view to Source view), you will see that an attribute has been added to our Button control, telling
which method to call when the button is clicked. All this work done with a simple doubleclick.

Now lets add some code to our new event. We wish to use the text from the TextBox, on our good old
Label with the "Hello, world!" text. This is also very simple, and all it requires is a single line of code:
HelloWorldLabel.Text = "Hello, " + TextInput.Text;

Run the project again (F6), and you will see the our old page with a couple of new controls. The
"Hello, world!" text is still there, because we set it in the Page_Load event. Now try entering a name in
the textbox, and press the button. Voila, the text is changed, and we have just used our first control
event. Notice how we can add code which is not necessarily called unless the user performs a specific
task. This is different from the good old Classic ASP/PHP approach, but you will soon get used to it,
and you will probably also come to like it a lot!

More events
Okay, the onclick event from last chapter was easy, but let's try creating all the code required to use an
event from scratch. We will also add yet a new control, to make things more interesting - the
DropDownList, which allows the user to select an item from a list. Add the folowing code snippet
somewhere in the Default.aspx file:

<asp:DropDownList runat="server" id="GreetList" autopostback="true">


<asp:ListItem value="no one">No one</asp:ListItem>
<asp:ListItem value="world">World</asp:ListItem>
<asp:ListItem value="universe">Universe</asp:ListItem>
</asp:DropDownList>

This thing works just like a normal HTML SELECT element, which is of course what it's translated
into upon rendering. The only attribute that would seem new to a person with basic HTML experience,
is the autopostback. You will learn more about postbacks in one of the next chapters, but for now, just
know that it makes the control contact the server eachtime an item is selected by the user. We will use
this to our benefit now, by adding an event:
<asp:DropDownList runat="server" id="GreetList" autopostback="true"
onselectedindexchanged="GreetList_SelectedIndexChanged">

We are using the onselectedindexchanged event, and assigning a method from CodeBehind which does
not yet exist. You are free to choose the name of the method, but using a convention with the name of
the control, an underscore, and then the name of the event, helps you keep track of it all. We better go
create the event, so change to the Default.aspx.cs file, and add the following method:
protected void GreetList_SelectedIndexChanged(object sender, EventArgs e)
{
HelloWorldLabel.Text = "Hello, " + GreetList.SelectedValue;
}

Once again, we make this extremely simple. We use the SelectedValue property of our dropdown list,
which holds the text from the value property of the selected item. Try running the site, and select an
item from the dropdown list. Pretty neat, huh? All commen controls come with a bunch of usefull
events, which you can subscribe to like this.

UserControls - Introduction
A UserControl is a separate, reusable part of a page. You can put a piece of a page in a UserControl,
and then reuse it from a different location. The name, UserControl, might seem a bit fancy, but actually,
it's just like a regular page, with an optional CodeBehind file. A notable difference is that UserControls
can be included on multiple pages, while a page can't. UserControls are used much like regular server
controls, and they can be added to a page declaratively, just like server controls can.

A big advantage of the UserControl is that it can be cached, using the OutputCache functionality
described in a previous chapter, so instead of caching an entire page, you may cache only the
UserControl, so that the rest of the page is still re-loaded on each request.

An example where a UserControl could come in handy, is a control for showing information about a
certain user on a community website. In the next couple of chapters, we will create a UserControl from
scratch, make it fit to our purpose, and then use it on a page.

Creating a UserControl
Okay, so we will be building a UserControl for displaying information about a community user. First of
all, let's add a UserControl to our project. In your Visual Studio, you should be able to right click on
your project and select Add new item.. A dialog will pop up, and you should select the Web User
Control from the list of possible things to add. Let's call our UserControl UserInfoBoxControl, with the
filename of UserInfoBoxControl.ascx. Make sure that you have checked the checkbox which places
code in a separate file, the so-called CodeBehind file.

You should now have a UserInfoBoxControl.ascx and a UserInfoBoxControl.ascx.cs in your project.


The first is where we put our markup, and the second is our CodeBehind file. Now, if
UserInfoBoxControl.ascx is not already open and selected, do so now. You will see only one line of
code, the UserControl declaration. As mentioned, this control will be displaying information about a
user, so let's get started adding some markup to do so:

<%@ Control Language="C#" AutoEventWireup="true"


CodeFile="UserInfoBoxControl.ascx.cs" Inherits="UserInfoBoxControl" %>
<b>Information about <%= this.UserName %></b>
<br /><br />
<%= this.UserName %> is <%= this.UserAge %> years old and lives in <%=
this.UserCountry %>
As you can see, it's all very basic. We have a declaration, some standard tags, some text, and then we
have some sort of variables. Now, where do they come from? Well, right now, they come from
nowhere, since we haven't declared them yet. We better do that right away. Open the CodeBehind file
for the UserControl, that is, the one which ends on .cs.

As you can see, it looks just like a CodeBehind file for a regular page, except that it inherits from
UserControl instead of from Page. We will declare the tree properties used in our markup, and base
them on three corresponding fields.
private string userName;
private int userAge;
private string userCountry;

public string UserName


{
get { return userName; }
set { userName = value; }
}

public int UserAge


{
get { return userAge; }
set { userAge = value; }
}

public string UserCountry


{
get { return userCountry; }
set { userCountry = value; }
}

It's all very simple and works just like a regular class. You can even add methods, if you feel like it!
Our UserControl is actually done now, but as you may have already experienced, we can't use it yet. A
UserControl can't be displayed directly in the browser - it has to be included on a page. We will do that
in the next chapter.

Using a UserControl
In the previous chapter we created a UserControl, and now we will try using it for the first time. Pick a
page in your project, or simply create a new one for the purpose, and open it. The first thing we have to
do, is declare our UserControl. It can be done either in each page where it's used, or globally in the
web.config file. There is no performance difference, but when declaring UserControls in the
web.config file, the controls have to reside in a different directory than the page(s) using it.

For now, let's just declare it within the page. Add the following line below the standard page
declaration:

<%@ Register TagPrefix="My" TagName="UserInfoBoxControl"


Src="~/UserInfoBoxControl.ascx" %>

Make sure that the src value matches the path to your UserControl file. Now you may use the
UserControl in your page, like any other control. For instance, like this:
<My:UserInfoBoxControl runat="server" ID="MyUserInfoBoxControl" />

If you look at the page now, you will see our UserControl in action, although the information will be a
bit... limited. We will have to set a value for the properties we defined, for things to get just a bit more
interestingly. Fortunately, it's very easy:
<My:UserInfoBoxControl runat="server" ID="MyUserInfoBoxControl" UserName="John Doe"
UserAge="45" UserCountry="Australia" />

You see, every public or protected member can be accessed declaretively, allowing easy access to them
when we use our control. However, with this specific UserControl, chances are that you will be
receiving the information from an external resource, like a database, and then populating the
UserControl from there. This usually involves the CodeBehind of the page, so how can we do that?
Pretty simple, actually. In the CodeBehind of the page, try something like this:
protected void Page_Load(object sender, EventArgs e)
{
// These values can come from anywhere, but right now, we just hardcode them
MyUserInfoBoxControl.UserName = "Jane Doe";
MyUserInfoBoxControl.UserAge = 33;
MyUserInfoBoxControl.UserCountry = "Germany";
}

Loading dynamically
Sometimes you may wish to add UserControls to your page dynamically instead of declaring them. It's
actually quite simple too. You need an existing control where you can add the UserControl to, for
instance a Panel. If there's no logical control on your page to add it to, you may create one for the
purpose - the PlaceHolder control is for situations just like that.

On your page, define it like this:

<asp:PlaceHolder runat="server" ID="phUserInfoBox" />

In the CodeBehind of the page, we add the control like this:


phUserInfoBox.Controls.Add(LoadControl("~/UserInfoBoxControl.ascx"));

We use the LoadControl method to instantiate the UserControl by specifying the path. This is very easy,
but also very anonymous - because we just use the LoadControl method, we can't really use our own,
custom properties. To do that, we need to make .NET aware of it. On the page, add the following
declaration in the top:
<%@ Reference Control="~/UserInfoBoxControl.ascx" %>

Now we can access the UserInfoBoxControl class like if it were a regular class, which also means that
we can typecast the UserControl returned by the LoadControl method to this type. In the next example,
we do just that, then we set the properties, and at last, we add it to the PlaceHolder:
UserInfoBoxControl userInfoBoxControl =
(UserInfoBoxControl)LoadControl("~/UserInfoBoxControl.ascx");
userInfoBoxControl.UserName = "John Doe";
userInfoBoxControl.UserAge = 78;
userInfoBoxControl.UserCountry = "Spain";
phUserInfoBox.Controls.Add(userInfoBoxControl);

This will come in handy, for instance when you're adding multiple instances of the same UserControl to
a single page, because you can do it inside a loop.

Events in UserControls
In a previous chapter, we looked at defining properties for our UserControl, but events can be declared
and used as well! This allows you to encapsulate even more functionality inside your controls, and then
let your page respond to certain events, triggered by the control, if necessary.

For this chapter, we will create a new and very simple UserControl, to illustrate how to create events. It
won't have a real life purpose, but is only meant to show you how to use events in a UserControl. If you
don't know how to create and use a UserControl, then please go back a few chapters. This one will
focus on the event part.

First, we create a new, simple EventUserControl, with this code in it:

<%@ Control Language="C#" AutoEventWireup="true"


CodeFile="EventUserControl.ascx.cs" Inherits="EventUserControl" %>
Page title:
<asp:TextBox runat="server" ID="txtPageTitle" />
<asp:Button runat="server" ID="btnUpdatePageTitle"
OnClick="btnUpdatePageTitle_Click" Text="Update" />

All just text and server controls that we know. In the CodeBehind, it looks a bit like this:
public partial class EventUserControl : System.Web.UI.UserControl
{
private string pageTitle;
public event EventHandler PageTitleUpdated;

protected void btnUpdatePageTitle_Click(object sender, EventArgs e)


{
this.pageTitle = txtPageTitle.Text;
if(PageTitleUpdated != null)
PageTitleUpdated(this, EventArgs.Empty);
}

public string PageTitle


{
get { return pageTitle; }
}
}

We have defined a pageTitle container variable and a property for it. Then we have a new thing, an
event. As you can see, it's defined much like any other kind of field, but it is a bit different. The theory
about is explained in the C# tutorial, so we won't get into that here.
In the Click event of our button, we set the pageTitle field. Then we check if PageTitleUpdated, our
event, is null. If it's not, it means that we have subscribed to this event somewhere, and in that case, we
send a notification by calling the PageTitleUpdated as a method. As parameters, we send this (a
reference to the UserControl it self) as the sender, and an empty EventArgs parameter. This will make
sure that all subscribers are notified that the pageTitle has just been updated. Now, in our page, I've
declared our UserControl like this:

<%@ Register TagPrefix="My" TagName="EventUserControl"


Src="~/EventUserControl.ascx" %>

And inserted it like this:


<My:EventUserControl runat="server" ID="MyEventUserControl"
OnPageTitleUpdated="MyEventUserControl_PageTitleUpdated" />

As you can see, we have defined an event handler for the PageTitleUpdated event like if it was any
other server control. In the CodeBehind of our page, we define the simple event handler for the
UserControl event like this:
protected void MyEventUserControl_PageTitleUpdated(object sender, EventArgs e)
{
this.Title = MyEventUserControl.PageTitle;
}

It's that simple! Now obviously, updating the page title could have been done directly from our
UserControl, so it's just to provide a simple example on how to use events, but as you will likely learn
later on, this technic will come in handy in lots of situations.

Validation - Introduction
Ever since the first dynamic website was created, form validation has been an important subject.
Getting user input through the system requires much attention, and with previous serverside scripting
languages, there were no standard way of dealing with form validation. For that reason, clientside
scripting has been used in many cases, but as you probably know, clientside scripting is not bulletproof
- it can easily be bypassed or simply turned off. With ASP.NET, webdevelopers were finally given a
good, standard set of tools for validating forms. The validation controls of ASP.NET is based on both
clientside and serverside technology, which brings the best from both worlds, to make sure that
validating a form is as easy as ever.

ASP.NET 2.0, which is the latest version as I write this, comes with several different validation controls
for different purposes. In the following chapters, we will show examples of each of them. They all
work in different ways, but essentially they do the same - they make sure that a form field has been
properly filled by the user.

Validation - RequiredFieldValidator
The RequiredFieldValidator is actually very simple, and yet very useful. You can use it to make sure
that the user has entered something in a TextBox control. Let's give it a try, and add a
RequiredFieldValidator to our page. We will also add a TextBox to validate, as well as a button to
submit the form with.

<form id="form1" runat="server">


Your name:<br />
<asp:TextBox runat="server" id="txtName" />
<asp:RequiredFieldValidator runat="server" id="reqName"
controltovalidate="txtName" errormessage="Please enter your name!" />
<br /><br />
<asp:Button runat="server" id="btnSubmitForm" text="Ok" />
</form>

Actually, that's all we need to test the most basic part of the RequiredFieldValidator. I'm sure that all the
attributes of the controls makes sense by now, so I won't go into details about them. Try running the
website and click the button. You should see something like this:

If your browser supports JavaScript, which most modern browers do, then you will notice that the page
is not being posted back to the server - the validation is performed clientside! This is one of the really
cool things about ASP.NET validators. Validation is only performed serverside if necessary! To see how
it feels, you can add enableclientscript="false" to the RequiredFieldValidator and try again. Now you
will see the browser posting back to the server, but the result will be the same - the validator still
works!

Right now, the button does nothing, besides posting back if the page is valid. We will change this by
adding an onclick event to it:

<asp:Button runat="server" id="btnSubmitForm" text="Ok"


onclick="btnSubmitForm_Click" />

In the CodeBehind file, we add the following event handler:


protected void btnSubmitForm_Click(object sender, EventArgs e)
{
if(Page.IsValid)
{
btnSubmitForm.Text = "My form is valid!";
}
}

As you will notice, we check whether or not the page is valid, before we do anything. This is very
important, since this code WILL be reached if the clientside validation is not used, for some reason.
Once it comes to serverside validation, it's your job to make sure that no sensitive code is executed
unless you want it to. As you see, it's very simple - just check the Page.IsValid parameter, and you're
good to go. Try to run the website again, and notice how the text of the button is changed if you submit
a valid form.
Validation - CompareValidator
The CompareValidator might not be the most commonly used validator of the bunch, but it's still
useful in some cases. It can compare two values, for instance the values of two controls. In the next
example, I will show you a small example of how it can be used.

Small number:<br />


<asp:TextBox runat="server" id="txtSmallNumber" /><br /><br />
Big number:<br />
<asp:TextBox runat="server" id="txtBigNumber" /><br />
<asp:CompareValidator runat="server" id="cmpNumbers"
controltovalidate="txtSmallNumber" controltocompare="txtBigNumber"
operator="LessThan" type="Integer" errormessage="The first number should be smaller
than the second number!" /><br />

As you see, we only use one validator to validate the two fields. It might seem a bit overwhelming, but
it's actually quite simple. Like with the RequiredFieldValidator, we use the controltovalidate attribute to
specify which control to validate. In addition to that, we specify a control to compare. The operator
attribute specifies which method to use when comparing. In this case, we use the LessThan operator,
because we wish for the first control to have the smallest value. We set the type to integer, because we
want to compare integers. Dates, strings and other value types can be compared as well.

Now, try running the website, and test the two new fields. Here is what happens if you don't fill out the
form correctly:

If you switch the numbers, you will see another cool thing about the ASP.NET validators and clientside
scripting: Validation is also performed upon exiting the fields. If you don't want this, you can turn off
clientside scripting with the enableclientscript attribute. You can also compare a field to a static value.
To do this, remove the controltocompare attribute, and add the valuetocompare attribute.

However, as you may have noticed, the content of the two textboxes is not checked before comparing
it. For instance, it would be possible to enter nothing, or enter a piece of text instead of a number. You
should always consider this when using the CompareValidator. You can protect against empty fields
with the RequiredFieldValidator, and you can protect against wrong values like text with for instance a
RegularExpressionValidator, which we will show you how to use a bit later.

If the clientside validation is not working, the invalid form will be catched by our piece of code in the
CodeBehind file, as shown with the RequiredFieldValidator. This is important.
Validation - RangeValidator
he RangeValidator does exactly what the name implies; it makes sure that the user input is within a
specified range. You can use it to validate both numbers, strings and dates, which can make it useful in
a bunch of cases. Since we validated numbers the last time, we will try with a date this time.

Date:<br />
<asp:TextBox runat="server" id="txtDate" />
<asp:RangeValidator runat="server" id="rngDate" controltovalidate="txtDate"
type="Date" minimumvalue="01-01-2006" maximumvalue="31-12-2006"
errormessage="Please enter a valid date within 2006!" />
<br /><br />

The date format might seem a bit weird to you if you're not from Europe, where we use dd-mm-yy. You
can just change it if it doesn't fit the date format on the machine you're working on. Now, try running
the website, and enter a date in our new TextBox. It's only valid if the date is within 2006, and a cool
sideeffect is that the date is also checked for validity. Have a look at this screenshot, which shows us
that the validator reacts to an impossible date as well:

And once again, if the clientside validation is not working, it will be catched in our CodeBehind, as
shown with the RequiredFieldValidator. If you missed this part, then be sure to check out the first
chapters!

Validation - RegularExpressionValidator
The RegularExpressionValidator is a bit more difficult to write about, because it requires knowledge
of Regular Expressions to really use it. However, RegularExpressionValidator is one of the most useful
validators, because it can be used to check the validity of any kind of string. If you don't feel like
learning Regular Expressions, but still feel like using this validator, have a look around the Internet.
You can find many pre-made expressions out there, which can be very useful to you. Here is an
example where we require a 4 digit number - nothing else is acceptable:

4 digit number:<br />


<asp:TextBox runat="server" id="txtNumber" />
<asp:RegularExpressionValidator runat="server" id="rexNumber"
controltovalidate="txtNumber" validationexpression="^[0-9]{4}$"
errormessage="Please enter a 4 digit number!" />
<br /><br />

The only new attribute we use, is the validationexpression. This attribute simply holds the Regular
Expression which should be used to validate the field. Since Regular Expressions are beyond the scope
of this tutorial, I won't try to explain it, other than it simply tells the validator that a value of 4 digitgs is
acceptable, and nothing else. You can use the RegularExpressionValidator for almost everything, for
instance validating an e-mail or an URL.
Try switching to Design view and select the RegularExpressionValidator on your page. Now have a
look in the Properties tab of Visual Studio. The ValidationExpression attribute has a button next to it,
and if you click it, you will gain access to some default expressions, delivered by the ASP.NET team,
for various purposes. Just select one of them, to use in your validator.

Validation - CustomValidator
If none of the other validators can help you, the CustomValidator usually can. It doesn't come with a
predefined way of working; you write the code for validating your self. This is of course very powerful,
since the possibilities are basically endless. A common way of using the CustomValidator is when you
need to make a database lookup to see if the value is valid. Since this tutorial hasn't treated database
access yet, we will do a simpler example, but hopefully you will see that you can do just about
everything with the CustomValidator. The control allows you to validate both clientside and serverside,
where the serverside approach is probably the most powerful. Of course, doing serverside validation
requires a postback to validate, but in most cases, that's not really a problem.

In this example, we will simply check the length of the string in the TextBox. This is a very basic and
that useful example, only made to show you how you may use the CustomValidator.

Custom text:<br />


<asp:TextBox runat="server" id="txtCustom" />
<asp:CustomValidator runat="server" id="cusCustom" controltovalidate="txtCustom"
onservervalidate="cusCustom_ServerValidate" errormessage="The text must be exactly
8 characters long!" />
<br /><br />

As you can see, it's pretty simple. The only unknown property is the onservervalidate event. It's used to
reference a method from CodeBehind which will handle the validation. Switch to our CodeBehind file
and add the following method:
protected void cusCustom_ServerValidate(object sender, ServerValidateEventArgs e)
{
if(e.Value.Length == 8)
e.IsValid = true;
else
e.IsValid = false;
}

This is very simple. The validator basically works by setting the e.IsValid boolean value to either true
or false. Here we check the e.Value, which is the string of the control being validated, for it's length. If
it's exactly 8 characters long, we return true, otherwise we return false.

More validation
The validators all share a couple of attributes, which can be very useful in some cases.

ValidationGroup
This attribute was introduced with ASP.NET 2.0, and makes it possible to divide your form elements
into groups. Usually, a validator control is always triggered on a postback, which could sometimes lead
to problems. For instance, if you have a contact form and a search field on the same page, the
validation of the contact form could be triggered by the Search button, preventing the user from
searching before filling out the contact form. You can assign a name in the validationgroup property,
for both the validators and the button(s) that you wish to be able to trigger the validation. The value of
the attribute can be a number or a name, like validationgroup="contact_form".

SetFocusOnError (true|false)
This attribute was also introduced with ASP.NET 2.0, and it does exactly what the name implies. Set
SetFocusOnError to true on one or several of your validators, to give focus to the first invalid field
when the form is validated.

Display (Dynamic|None|Static)
This attribute decides how the validator is rendered to your page. The default value is Static, which
makes the validator take up the required place whether it's visible (active) or not. You can test this by
placing a piece of text directly behind a validator and load the page. If you have not set the Display
attribute, or if you have set it to Static, you will see that the text is moved. However, if you set it to
Dynamic, the validator will only take up any space if the validation fails and the validator is activated.
This can be convenient in some cases, where you need the space the validator can take up otherwise. If
you set it to None, the error message will never be shown.

Introduction to caching
One of the really cool features of ASP.NET is the caching. With other technologies, caching usually
requires some extra software or at least complicated code, but with ASP.NET 2.0, it's easier than ever
before. You can use two different kinds of caching - output caching and standard caching. The first one
is the easiest, so let's start with that. In the following chapters we will use various forms of the
OutputCache directive, as well as the ASP.NET Cache object. Read on.

OutputCache
In this chapter, we will take a look at the OutputCache directive, which is by far the easiest way of
caching content with ASP.NET. As you will see in our example, it doesn’t even require any code – only
some minor changes to the markup of the page, and you’re good to go. In the next chapter, we will look
into more ways of using the OuputCachce directive.

Here is a very simple example of a page which will show us the difference between a cached page and
a non-cached page. Try creating a new project, and change the Default.aspx page to contain the
following markup:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"


Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Caching</title>
</head>
<body>
<form id="form1" runat="server">
<%= DateTime.Now.ToString() %>
</form>
</body>
</html>

This is all standard stuff, except the line with the DateTime. It simply outputs the current date and time
to the page. Try running the project and reload the page a couple of times. As you will see, the time is
refreshed on each reload. Now, add the following line as line number 2 to our example:
<%@ OutputCache duration="10" varybyparam="None" %>

Run our project again, and reload the page a number of times. As you will see, the time is only
refreshed every 10 seconds. Adding caching to your page is as simple as that! Now, the duration
parameter is pretty obvious - it tells the page how many seconds to cache the content. Each time the
page is requested, ASP.NET checks if the page is in the cache, and if it is, whether or not it has expired.
It's served from the cache if it isn't expired - if it is, the page is removed from the cache and the page is
generated from scratch and then placed in the cache.

The varybyparam is a required parameter of the OutputCache directive. It specifies a list of parameters
which the the cache should be varied by. For instance, if you set it to "p", the cache is now depending
on the value of the parameter p. Try changing our example to something like this:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<%@ OutputCache duration="10" varybyparam="p" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Caching</title>
</head>
<body>
<form id="form1" runat="server">
<%= DateTime.Now.ToString() %><br />
<a href="?p=1">1</a><br />
<a href="?p=2">2</a><br />
<a href="?p=3">3</a><br />
</form>
</body>
</html>

Now, run our example again, and try clicking the links. They each now have their own timestamp,
based on when you first accessed the page. The cache is depending on the value of the p parameter!
You can specify multiple parameters by seperating them with a semicolon.

OutputCache - more examples


In the last chapter, we looked at using the OutputCache directive to cache our page very simply. In this
chapter, we will look into other ways of using the OutputCache. We used varybyparam in the previous
example, but you can vary your cache by other factors as well. Here is a brief list and some examples.
OutputCache - varybyparam

Please see the previous chapter for more information on the varybyparam parameter.

OutputCache - varybycontrol

The varybycontrol does exactly what it says - it varies the cache depending on the value of the
specified control. For instance, you can have a dropdownlist with a set of selections, and base the
content of the page based on the selected item. In that case, it will make sense to vary by the value of
this control, since the content of the page changes according to it. Here is an example of using the
varybycontrol parameter:

<%@ OutputCache duration="10" varybyparam="none" varybycontrol="NameOfControl" %>

OutputCache - varybycustom

This is probably the least easy way of using the OutputCache system, but on the other hand, probably
the most flexible. It allows you to handle the variations your self, by setting a custom string, which
ASP.NET will vary the output by. To test this, you need to add a global.asax file to your project, if you
don't already have one. Right click on your project in the Solution Explorer, and select Add new item.
Now select the "Global Application Class" and click Ok. In the Global.asax file, you need to override
the GetVaryByCustomString like this:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if(custom == "Browser")
{
return context.Request.Browser.Browser;
}
return String.Empty;
}

In this case, our caching will be varied based on which browser the user accesses the page with. The
markup part should be written like this:
<%@ OutputCache duration="120" varybyparam="None" varybycustom="Browser" %>

Try accessing the page from different browsers. You will see that the output now depends on which
browser you use. The Browser object comes with a bunch of useful information about the client
browser - for instance you could vary by whether or not the browser supports CSS, JavaScript or
something else.

OutputCache - varybyheader

This one allows you to vary the content based on one or more of the headers that browser send. Here is
an example:
<%@ OutputCache duration="120" varybyparam="None" varybyheader="Accept-Language" %>

This will vary cache based on the Accept-Language header, which tells the server which languages the
user accepts and prefers.
OutputCache - Substitution
With ASP.NET version 1.0 and 1.1, there was no way to control which parts of a page would be cached,
and more importantly: Which parts would be generated on each request no matter what. That meant
that whenever you needed just a small part of the page to refreshed on each request, the OutputCache
directive could not be used. This has changed with ASP.NET 2.0, where we may use the
<asp:Substitution> tag to make areas exist outside the cached content. Have a look at the following
example:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"


Inherits="_Default" %>
<%@ OutputCache duration="120" varybyparam="None" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Caching</title>
</head>
<body>
<form id="form1" runat="server">
Cached datestamp:<br />
<%= DateTime.Now.ToString() %><br /><br />
Fresh datestamp:<br />
<asp:Substitution runat="server" id="UnCachedArea"
methodname="GetFreshDateTime" />
</form>
</body>
</html>

The Substitution tag takes an attribute called methodname, which holds the name of a method which
should return the string to output. Once the page is loaded, no matter if it's returned from the cache or
freshly generated, this method will be called, and the Substitution control will be filled with the
returned string. Here is the CodeBehind, where you will see our GetFreshDateTime method:
using System;
using System.Data;
using System.Web;

public partial class _Default : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{
}

protected static string GetFreshDateTime(HttpContext context)


{
return DateTime.Now.ToString();
}
}

Since the GetFreshDateTime method needs to be called by the Substitution control, it needs to "look" a
certain way - it has to take the HttpContext as a parameter, it has to return a string, and it has to be
static. Now, the HttpContext allows you to access all kinds of information about the request etc. to use
for returning the proper value. For now, we simply return the current datetime. Run the example, and
see how the first datestamp is cached, while the second is reloaded each time. It's as simple as that!
Caching objects
While the OutputCache directive is easy to use and work with, it allows you only to cache the entire
page, or an entire UserControl. While this is just fine for some situations, there will be times where
caching an object will be much smarter. While the following example might seem a bit silly, it does
show how the Cache object can be used to store for instance an ArrayList with custom objects in it.
Create a new project, or use an existing page and change the CodeBehind Page_Load method to
something like this (this example doesn't require you to modify the markup part):

protected void Page_Load(object sender, EventArgs e)


{
ArrayList datestamps;
if(Cache["datestamps"] == null)
{
datestamps = new ArrayList();
datestamps.Add(DateTime.Now);
datestamps.Add(DateTime.Now);
datestamps.Add(DateTime.Now);

Cache.Add("datestamps", datestamps, null,


System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 0, 60),
System.Web.Caching.CacheItemPriority.Default, null);
}
else
datestamps = (ArrayList)Cache["datestamps"];

foreach(DateTime dt in datestamps)
Response.Write(dt.ToString() + "<br />");
}

Try running this example and reloading the page. 3 instances of the current date is placed in an
ArrayList, and the list is then cached using the Cache object. On each page load, the Cache is checked
to see if it contains our ArrayList, using a name we have provided. If it's not, the list is generated, filled
and cached. If the ArrayList is already in the cache, we pull it out and cast it to the correct type
(everything is stored as object types). No matter where we get the list from, we iterate through it and
output each value.

Most of it should be pretty straight forward, except for the line where we add the list to the Cache. The
Add method takes a bunch of parameters, and I will try to explain all of them.

First of all, the key we wish to store our object by, in this case we simply call it "datestamps". The key
is used to get the object back from the Cache.

Next parameter is the object we wish to cache, so that goes without explaining.

Next up is the CacheDependency parameter. It can be used to tell ASP.NET that the cached item
depends on other items, allowing ASP.NET to invalidate the cache if one of these items changes.

The following two parameters tells ASP.NET how and when the item should expire in the cache. The
first one specifies an absolute expiration, meaning that the item will expire at a certain time of day. This
is usually not what you want, so we set it to NoAbsoluteExpiration. Next we can specify a sliding
expiration, which means that the item will expire after a certain amount of time, based on when the
item is placed in the cache. The TimeSpan class is used, and we specify that it should expire after 0
hours, 0 minutes and 60 seconds. A priority can be set for the item in the cache. This is used when
ASP.NET is removing items from the cache - items with a lower priority are removed first.

The last parameter allows us to specify a callback function for the item, which will be called once the
item is removed from the cache, in case you need that. We simply specify a null value.

So, as you can see, storing items by using the Cache object is really easy. Of course, we don't really
earn any performance in this example, but only the imagination is the limit here. One of the most
common practices are storing objects retrieved from a database in the cache, so save resources on the
database machine and allow for faster loading pages.It is important that when you are installing this
onto your site that you have extra Cyber Protection to prevent your site from being hacked and utilizing
the cache.

Cookies
Cookies are small pieces of text, stored on the client's computer to be used only by the website setting
the cookies. This allows webapplications to save information for the user, and then re-use it on each
page if needed. Here is an example where we save a users choice of background color:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"


Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Cookies</title>
</head>
<body runat="server" id="BodyTag">
<form id="form1" runat="server">
<asp:DropDownList runat="server" id="ColorSelector" autopostback="true"
onselectedindexchanged="ColorSelector_IndexChanged">
<asp:ListItem value="White" selected="True">Select color...</asp:ListItem>
<asp:ListItem value="Red">Red</asp:ListItem>
<asp:ListItem value="Green">Green</asp:ListItem>
<asp:ListItem value="Blue">Blue</asp:ListItem>
</asp:DropDownList>
</form>
</body>
</html>

The page simply contains a DropDownList control, which automatically posts back each time a new
item is selected. It has 3 different colors, besides the default one, which is simply white. Once a new
item is selected, the ColorSelector_IndexChanged method is fired, from our CodeBehind file:
using System;
using System.Data;
using System.Web;

public partial class _Default : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{
if(Request.Cookies["BackgroundColor"] != null)
{
ColorSelector.SelectedValue = Request.Cookies["BackgroundColor"].Value;
BodyTag.Style["background-color"] = ColorSelector.SelectedValue;
}
}

protected void ColorSelector_IndexChanged(object sender, EventArgs e)


{
BodyTag.Style["background-color"] = ColorSelector.SelectedValue;
HttpCookie cookie = new HttpCookie("BackgroundColor");
cookie.Value = ColorSelector.SelectedValue;
cookie.Expires = DateTime.Now.AddHours(1);
Response.SetCookie(cookie);
}
}

Okay, two different parts to be explained here. First, the Page_Load method, which is called on each
page request. Here we check for a cookie to tell us which background color should be used. If we find
it, we set the value of our dropdown list to reflect this, as well as the background color of the page,
simply by accessing the style attribute of the body tag.
Then we have the ColorSelector_IndexChanged method, which is called each time the user selects a
new color. Here we set the background color of the page, and then we create a cookie, to hold the value
for us. We allow it to expire after one hour, and then we set it by calling the SetCookie method on the
Response object.

Try running the example, and set a color. Now close the browser, and start it up again. You will see that
the choice of color is saved, and it will remain saved for an hour. However, nothing prevents you from
saving the choice for much longer. Simply add a bigger value to the expiry date, or set an absolute
value for it.

Sessions
Sessions can be used to store even complex data for the user just like cookies. Actually, sessions will
use cookies to store the data, unless you explicitly tell it not to. Sessions can be used easily in ASP.NET
with the Session object. We will re-use the cookie example, and use sessions instead. Keep in mind
though, that sessions will expire after a certain amount of minutes, as configured in the web.config file.
Markup code:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"


Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Sessions</title>
</head>
<body runat="server" id="BodyTag">
<form id="form1" runat="server">
<asp:DropDownList runat="server" id="ColorSelector" autopostback="true"
onselectedindexchanged="ColorSelector_IndexChanged">
<asp:ListItem value="White" selected="True">Select color...</asp:ListItem>
<asp:ListItem value="Red">Red</asp:ListItem>
<asp:ListItem value="Green">Green</asp:ListItem>
<asp:ListItem value="Blue">Blue</asp:ListItem>
</asp:DropDownList>
</form>
</body>
</html>

And here is the CodeBehind:


using System;
using System.Data;
using System.Web;

public partial class _Default : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{
if(Session["BackgroundColor"] != null)
{
ColorSelector.SelectedValue = Session["BackgroundColor"].ToString();
BodyTag.Style["background-color"] = ColorSelector.SelectedValue;
}
}

protected void ColorSelector_IndexChanged(object sender, EventArgs e)


{
BodyTag.Style["background-color"] = ColorSelector.SelectedValue;
Session["BackgroundColor"] = ColorSelector.SelectedValue;
}
}

As you can see, the example doesn't need a lot of changes to use sessions instead of cookies. Please
notice that session values are tied to an instance of your browser. If you close down the browser, the
saved value(s) will usually be "lost".
Also, if the webserver recycles the aspnet_wp.exe process, sessions are lost, since they are saved in
memory as well. This can be avoided by saving session states on a separate StateServer or by saving to
a SQL server, but that's beyond the scope of this article.

ViewState
Another approach to saving data for the user, is the ViewState. As described elsewhere in this tutorial,
the ViewState allows ASP.NET to repopulate form fields on each postback to the server, making sure
that a form is not automatically cleared when the user hits the submit button. All this happens
automatically, unless you turn it off, but you can actually use the ViewState for your own purposes as
well. Please keep in mind though, that while cookies and sessions can be accessed from all your pages
on your website, ViewState values are not carried between pages. Here is a simple example of using the
ViewState to carry values between postbacks:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"


Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>ViewState</title>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox runat="server" id="NameField" />
<asp:Button runat="server" id="SubmitForm" onclick="SubmitForm_Click"
text="Submit & set name" />
<asp:Button runat="server" id="RefreshPage" text="Just submit" />
<br /><br />
Name retrieved from ViewState: <asp:Label runat="server" id="NameLabel" />
</form>
</body>
</html>

And the CodeBehind:


using System;
using System.Data;
using System.Web;

public partial class _Default : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{
if(ViewState["NameOfUser"] != null)
NameLabel.Text = ViewState["NameOfUser"].ToString();
else
NameLabel.Text = "Not set yet...";
}

protected void SubmitForm_Click(object sender, EventArgs e)


{
ViewState["NameOfUser"] = NameField.Text;
NameLabel.Text = NameField.Text;
}
}

Try running the project, enter your name in the textbox and press the first button. The name will be
saved in the ViewState and set to the Label as well. No magic here at all. Now press the second button.
This one does nothing at all actually, it just posts back to the server.

Sending e-mails
Sending e-mails with ASP.NET is pretty straight forward. The .NET framework comes with an entire
namespace for handling e-mails, the System.Net.Mail namespace. In the following examples, we will
use two classes from this namespace: The MailMessage class, for the actual e-mail, and the SmtpClient
class, for sending the e-mail.

As you may be aware, mails are sent through an SMTP server, and to send mails with the .NET
framework, you will need access to an SMTP server. If you're testing things locally, the company that
supplies your with Internet access, will usually have an SMTP server that you can use, and if you wish
to use one of these examples on your actual website, the company that hosts your website will usually
have an SMTP server that you can use. Go through the support pages to find the actual address - it's
usually something along the lines of smtp.your-isp.com or mail.your-isp.com.
Once you have an accessible SMTP server, we're ready to send our very first e-mail. For the first
example, all you need is an empty page, with the following code in the CodeBehind:
protected void Page_Load(object sender, EventArgs e)
{
try
{
MailMessage mailMessage = new MailMessage();
mailMessage.To.Add("your.own@mail-address.com");
mailMessage.From = new MailAddress("another@mail-address.com");
mailMessage.Subject = "ASP.NET e-mail test";
mailMessage.Body = "Hello world,\n\nThis is an ASP.NET test e-mail!";
SmtpClient smtpClient = new SmtpClient("smtp.your-isp.com");
smtpClient.Send(mailMessage);
Response.Write("E-mail sent!");
}
catch(Exception ex)
{
Response.Write("Could not send the e-mail - error: " + ex.Message);
}
}

That's actually all you need to send an e-mail. We create a new MailMessage instance, add a new
receiver, set the "From" address and the subject, and then we write a simple test message for the body
of the e-mail. After that, we create a new instance of the SmtpClient, with the host address of the SMTP
server that you may use as a parameter, and then we use the SmtpClient instance to shoot the e-mail out
into cyberspace. The entire thing is surrounded by a try..catch block, just in case something goes
wrong.

This was just a very basic example, but there are a lot of other options. Here is a short list with
interesting ideas:

You can attach one or several files, simply by adding them to the Attachments collection. In this
example, we attach a file called "image.jpg", located in the root of the ASP.NET website:
mailMessage.Attachments.Add(new Attachment(Server.MapPath("~/image.jpg")));

You can send to more than one person at the same time, simply by adding another e-mail address to
the "To" collection, like this:
mailMessage.To.Add("your.own@mail-address.com");
mailMessage.To.Add("another@mail-address.com");

You can set a name for the sender - otherwise, only the e-mail address will be shown in the "From"
column of the receivers e-mail client. For instance, like this:
mailMessage.From = new MailAddress("me@mail-address.com", "My Name");

You can send HTML e-mails, instead of the default plaintext mails, to use more complicated layouts.
Here is a simple example:
mailMessage.IsBodyHtml = true;
mailMessage.Body = "Hello <b>world!</b>";

You can use the CC and BCC fields, just like in regular e-mail messages, like this:
mailMessage.CC.Add("me@mail-address.com");
mailMessage.Bcc.Add("me2@mail-address.com");

You can set the priority of an e-mail, like this:


mailMessage.Priority = MailPriority.High;

FileUpload control
With ASP.NET, accepting file uploads from users has become extremely easy. With the FileUpload
control, it can be done with a small amount of code lines, as you will see in the following example.
However, please notice that there are security concerns to to consider when accepting files from users!
Here is the markup required:

<form id="form1" runat="server">


<asp:FileUpload id="FileUploadControl" runat="server" />
<asp:Button runat="server" id="UploadButton" text="Upload"
onclick="UploadButton_Click" />
<br /><br />
<asp:Label runat="server" id="StatusLabel" text="Upload status: " />
</form>

And here is the CodeBehind code required to handle the upload:


protected void UploadButton_Click(object sender, EventArgs e)
{
if(FileUploadControl.HasFile)
{
try
{
string filename = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(Server.MapPath("~/") + filename);
StatusLabel.Text = "Upload status: File uploaded!";
}
catch(Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The
following error occured: " + ex.Message;
}
}
}

As you can see, it's all relatively simple. Once the UploadButton is clicked, we check to see if a file has
been specified in the upload control. If it has, we use the FileUpload controls SaveAs method to save
the file. We use the root of our project (we use the MapPath method to get this) as well as the name part
of the path which the user specified. If everything goes okay, we notify the user by setting the Text
property of the StatusLabel - if not, an exception will be thrown, and we notify the user as well.
This example will get the job done, but as you can see, nothing is checked. The user can upload any
kind of file, and the size of the file is only limited by the server configuration. A more robust example
could look like this:

protected void UploadButton_Click(object sender, EventArgs e)


{
if(FileUploadControl.HasFile)
{
try
{
if(FileUploadControl.PostedFile.ContentType == "image/jpeg")
{
if(FileUploadControl.PostedFile.ContentLength < 102400)
{
string filename = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(Server.MapPath("~/") + filename);
StatusLabel.Text = "Upload status: File uploaded!";
}
else
StatusLabel.Text = "Upload status: The file has to be less than
100 kb!";
}
else
StatusLabel.Text = "Upload status: Only JPEG files are accepted!";
}
catch(Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The
following error occured: " + ex.Message;
}
}
}

Here we use the two properties, ContentLength and ContentType, to do some basic checking of the file
which the user is trying to upload. The status messages should clearly indicate what they are all about,
and you can change them to fit your needs.

Introduction to localization
According to Wikipedia, "Localization is the process of adapting software for a specific region or
language by adding locale-specific components and translating text", and that is exactly what we'll look
into in the next couple of chapters. Offering your website in other languages than the default one can be
a big job, but fortunately, ASP.NET makes the process a lot easier.

There are quite a few concepts that you need to know about, right from the CultureInfo class to the
concepts of local and global resources, as well as implicit and explicit localization. In the next couple
of chapters, we will look into all of that, but first, let's see it in action, in our very own "Hello, localized
world!" example.

Hello, localized world!


With the knowledge acquired from the previous chapters, let's try actually localizing some text, to see
that it works. You should create a new project in Visual Studio. You can use the default page added, or
create a new one for the purpose. The content should look something like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs"


Inherits="Test" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Demo</title>
</head>
<body>
<form id="form1" runat="server">
<asp:Label runat="server" ID="lblHelloWorld" Text="Hello, world!" />
</form>
</body>
</html>

If you run it, you will get the good old "Hello, world!" message, in plain English as expected. Now let's
add some localization magic to it. We will use local, implicit localization for this - both are new terms,
which will be explained later on. For now, just right click on your project and from the Add ASP.NET
folder sub menu, select App_LocalResources. This is the folder where we place local resources, each
of them specific to a file in your project.

Now, right click this new folder, and add a new item. This should be a Resource file, and the name
should be the same as your page, but with a .resx extension. For instance, I called my page Test.aspx,
so my Resource file should be named Test.aspx.resx. This part is important - if we want ASP.NET to
automatically map a resource file to a specific ASP.NET page, the names should be like this. This is our
default resource file, used to keep the default version of our strings. Let's add a couple of other
languages. Once again, the filename is used to map the resource file, so for instance, to add a German
language file, the name should be <filename>.aspx.de.resx, or in the culture specific version:
<filename>.aspx.de-DE.resx

I have added Test.aspx.de-DE.resx and Test.aspx.es-ES.resx, to translate the page into German and
Spanish. Then I add a new row to Test.aspx.resx, with the name lblHelloWorld.Text. In my project,
English is the default language, so I give this row a value of "Hello, world!". I then open Test.aspx.de-
DE.resx, add a row with the same name as before, and set the value to "Hallo, Welt!". I do the same for
Test.aspx.es-ES.resx, where I set the value to "Hola, mundo!". Your three resource files should now all
have a row with the name of "lblHelloWorld.Text", and a localized version of the Hello world string.

Now, go back to our ASP.NET page and use the meta:resourcekey property on our Label control, to
make it use our resource string. It should look like this:
<asp:Label runat="server" ID="lblHelloWorld" Text="Hello, world!"
meta:resourcekey="lblHelloWorld" />

As you can see, I've used the same string as for the ID of the control. You probably remeber that we
added a resource row with the name of "lblHelloWorld.Text". This corresponds to a control with the
resource key of "lblHelloWorld", mapped to the Text property of this control. Now, try setting the
UICulture property on your page and run the example:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs"
Inherits="Test" UICulture="de-DE" %>

The label is now in German. Change UICulture to "es-ES" and reload the page. It's now in Spanish.
Then try changing it to something completely different, like fr-FR, and you will see our default
language used instead, simply because we don't have a localized version of the string in French.
This was a simple example, to show you how it can work, but you need a bit more information about
HOW it works. In the next couple of chapters we will look into local and global localization, as well as
implicit and explicit localization. First up is the CultureInfo class though, since it's used heavily when
doing localization.

The CultureInfo class


When it comes to localization of your application, especially one class is of great importance: The
CultureInfo class from the System.Globalization namespace. From this class, you can get information
about pretty much every possible culture out there, including a wide range of culture specific settings.
The CultureInfo class can really help you when localizing your webpages, most notably because
ASP.NET will keep a reference to the specific CultureInfo instance related to a specific visitor. Does it
sound complicated? Let me show you a little example:

<%@ Page Language="C#" Culture="Auto" %>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>CultureInfo demo</title>
</head>
<body>
<form id="MainForm" runat="server">
<% Response.Write("Your current culture: " +
System.Globalization.CultureInfo.CurrentCulture.DisplayName); %>
</form>
</body>
</html>

Try running this and you will get a culture related to you - but how? Actually, since the Culture
property of the Page directive is set to Auto, this is controlled by your browser. Most browsers allow
you to set your favorite languages, and from that, ASP.NET tries to detect which culture to use for you.
We will look into that in greater detail later on. Your current culture is used in lots of cases, for instance
when formatting dates and numbers, since that varies from culture to culture. Now, you may want to
use a specific culture, no matter what your visitors browser tells you. In that case, you can set the
Culture property of the page, like this:

<%@ Page Language="C#" Culture="en-US" %>

If you run the example now, you will get the output "English (United States)", which is the language of
English, with a specific US culture. English comes in other flavors too, for instance British or
Australian. en-US is considered a specific culture, where en (just English) is considered a neutral
culture, since it's just a language, not specific to any country. Now, to see the difference between two
cultures, try running this example:
<%@ Page Language="C#" Culture="en-US" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>CultureInfo demo</title>
</head>
<body>
<form id="MainForm" runat="server">
<% Response.Write("Current date, in a culture specific format: " +
DateTime.Now.ToString()); %>
</form>
</body>
</html>

Now, try changing the page Culture to a German one, like this:

<%@ Page Language="C#" Culture="de-DE" %>

You will see the exact same line of code output a different result, because it's culture dependant. But
you can actually output a culturally aware date (or number or anything else) without changing the
culture of the page. For instance, like this:
<% Response.Write("Current date, in a culture specific format: " +
DateTime.Now.ToString(System.Globalization.CultureInfo.GetCultureInfo("de-
DE").DateTimeFormat)); %>

We simply get a reference to a German culture, and then use it as a parameter to the ToString() method
on the DateTime class. CultureInfo comes with a NumberFormat property for formatting numbers too.
Obviously, formatting dates and numbers is just a small part of localizing an application, but the
CultureInfo class is (or at least can be) the foundation of this process, mainly because it's so well
integrated with the .NET framework, and in particular ASP.NET.

Culture vs. UICulture


This was all about the Culture property, but the Page class does come with another related property:
The UICulture property. UI stands for User Interface, so in fact, this is the property we can use to
identify the language used for the visual part of the page, while the Culture property is used for the
non-UI stuff, like date and number formatting, sorting and so on. In lots of situations, you would want
to use the same Culture and UICulture, but there are cases where you would want to separate these two,
for instance when you want the text of a website to be localized, while still outputting a consistent date
or number format, no matter where the user comes from.

Local & Global resources


When localizing your ASP.NET websites, you can store your resources as either a local or a global
resource. A local resource is specific to a certain page, which is the only one who can access it, while
global resources can be accessed from anywhere.

Local resources are kept in the special App_LocalResources folder, while global resources are kept in
the App_GlobalResources folder. Local and global resource files will look exactly the same, so the only
apparent difference, is the folder they're placed in. However, they are used differently. For instance,
with local resources, you need a resource file for each of your pages, and an extra one of each of the
desired languages. So if you have a website with 10 pages, each localized into two other languages,
besides the default language, it will amount to 30 resource files. With global resources, you would only
need (but not be limited to) one file per language, no matter how many pages you have. On the other
hand, each of these files could get pretty hard to manage, if your site has lots of localized content.

You will likely always need some global resources, but if you prefer, you may skip the local resources
and only use global ones. It's really up to you.
Implicit & Explicit localization
Implicit localization
Implicit localization is used within your markup, and its main advantage is that it allows you to localize
several properties of the same control/object, without explicitly referencing each property. In our
Localized Hello World chapter, we used it, and saw how we could set the meta:resourcekey property of
a control, and then automatically have its Text property mapped to the resource row in our resource file.
Let's expand a bit on that example, to have several properties localized. If you haven't already done so,
you should read the Localized Hello World chapter now and create the project from it, as the following
example uses it:
<asp:Label runat="server" ID="lblHelloWorld" Text="Hello, world!" Font-
Names="Verdana" ForeColor="Blue" meta:resourcekey="lblHelloWorld" />

In the three resource files we created (default, Germand and Spanish), you can now add two extra rows
to each of them, with the names "lblHelloWorld.ForeColor" and "lblHelloWorld.Font-Names", and then
define different values for it. For instance, the default label color could be blue, the German version
could be green and the Spanish version could be red, and you could define different font names for
each of them as well. This makes it really easy to localize e.g. controls, because we only have to define
the name of the resource row - each property is automatically mapped.

Explicit localization
With explicit localization, you pick out a specific resource row from your resource file, which is
returned to you, and while implicit localization can be helpful when localizing webcontrols and other
declarative objects, explicit localization is the only possible way of doing things in any other
circumstance. Let's see how the above example would look with explicit localization:
<asp:Label runat="server" ID="lblHelloWorld2" Text="<%$
Resources:lblHelloWorld.Text %>" Font-Names="<%$ Resources:lblHelloWorld.Font-Names
%>" ForeColor="<%$ Resources:lblHelloWorld.ForeColor %>" />

We simply re-use the resource rows from our previous example, and as you can see, the markup for
explicit localization is a bit more complicated and verbose than for implicit localization. The syntax for
retrieving a resource row is like this:
<%$ Resources:[resource class name,]RowName %>

As you can see, we didn't specify a resource class name in our example, because we use a local
resource. If you use a global resource, you should specify the name of the class it results it, which as a
rule of thumb is the same as the filename, but without the .resx extension. So for instance, if you have a
global resource file with the name of MyGlobalResources.resx, you would obtain a resource from it
like this:
<%$ Resources: MyGlobalResources,NameOfRow %>

As simple as that.
Localizing the CodeBehind
In the previous chapters, we only used localization for the markup part of the webpage, but localizing
your strings in Code Behind is just as simple. Here are the techniques for doing this, with some sample
code to get you started.

Direct access
Since the .NET framework takes your global resource files and turns them into strongly typed classes,
you can actually reference them as such. For instance, if you have a global resource file called
MyGlobalResources.resx, with a resource row with a name of HelloWorldString, you can access it like
this:
lblHelloWorld.Text = Resources.MyGlobalResources.HelloWorldString;

GetLocalResourceObject()
With a call to GetLocalResourceObject(), you can get a specific row from your local resource file. It is
returned as an object, but you can always call the ToString() method on it. For this to work, you have to
be within a file that has a local resource file. To get a row from it, simply specify the name of the row
as a parameter to the method, like this:
lblHelloWorld.Text = GetLocalResourceObject("lblHelloWorld.Text").ToString();

GetGlobalResourceObject()
The GetGlobalResourceObject() method works pretty much like the local version described above, but
for global resources instead. You have to specify an extra parameter though, to tell ASP.NET in which
global resource file you want to look for the row in, so the first parameter is the name of the resource
class generated from the resource file, while the secondary parameter is for specifying the name of the
row you're looking for, like this:
lblHelloWorld.Text = GetGlobalResourceObject("MyGlobalResources",
"HelloWorldString").ToString();

Which approach to use mostly depends on the situation and what you prefer, but the first one does have
a big advantage: Since it's strongly typed, the compiler will alert you if the row you are trying to
retrieve no longer exists, allowing you to catch any problems before they go into production.

Changing the active culture


In a previous chapter, we had a look at the CultureInfo class, and we briefly discussed how to change it
for a page. However, since changing the current culture is so essential, this chapter will contain an in-
depth look of the different ways to accomplish this.
Automatic
Both Culture and UICulture is automatically set based on the browser settings of your visitor. Try
running the following page:
<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>CultureInfo demo</title>
</head>
<body>
<form id="MainForm" runat="server">
<% Response.Write("Your current culture: " +
System.Globalization.CultureInfo.CurrentCulture.DisplayName); %>
</form>
</body>
</html>

Now, access your browsers language settings:

Internet Explorer: Click the Tools button, select Internet Options, then click the Languages button.

Firefox: Click the Tools menu, select Options, select the Content tab and then click the Choose button
in the Languages group.

Add another language, and then move it to the top of the list. Close the dialog and reload the page (F5).
You will now see the name of the culture matching your newly selected language.

The Page directive/class


As we saw in the previous chapter, we can simply define both Culture and UICulture by accessing the
properties in the Page directive:
<%@ Page Language="C#" Culture="en-US" UICulture="en-US" %>

Since the Page directive is just a shortcut to the Page class, this can be done from CodeBehind as well.
However, we have to do it at a certain point, before the page is being rendered, to make sure that it has
the desired effect. This is where the InitializeCulture() method comes into play, a method that is called
by ASP.NET pretty early in the Page life cycle, which you can override:
public partial class CultureInfoTest : System.Web.UI.Page
{
protected override void InitializeCulture()
{
Page.Culture = "en-GB";
Page.UICulture = "en-GB";
}

protected void Page_Load(object sender, EventArgs e)


{
Response.Write(Page.Culture);
}
}

You should be aware that the Page.Culture and Page.UICulture properties them self are merely
shortcuts to the System.Threading.Thread.CurrentThread.CurrentCulture and
System.Threading.Thread.CurrentThread.CurrentUICulture.

Globally
You can set the Culture and UICulture for all your pages, via the web.config file. Use the globalization
node, which is a child node of the system.web node, like this:
<globalization uiCulture="en-US" culture="en-US" />

If needed, you can still override this setting on individual pages.

MySQL - Introduction
MySQL is one of the most used database servers on the Internet. Part of its popularity comes from the
tight integration with PHP, but ASP.NET can use it as well. By using the Odbc classes from the .NET
framework, you can easily work with a MySQL database.

This tutorial will not cover installing MySQL, nor will it cover SQL in general. It will focus on using
MySQL with ASP.NET.

Follow the next chapters to get started with using MySQL together with ASP.NET. We will cover topics
from the first connection to databinding and much more.

MySQL - Getting started


The easiest way to use MySQL with ASP.NET is to use the MySQL ODBC Connector from MySQL
AB. If you're work is being hosted by a company which supports MySQL, they have probably already
installed this, but if you're testing your code on your own machine with your own instance of MySQL,
then you need to install this. MySQL Connector/ODBC 3.51 can be downloaded from this page:
http://dev.mysql.com/downloads/connector/odbc/3.51.html

Once installed, you will be able to connect to your MySQL database server. Doing so is quite easy, but
we will also need some data to test on. During the next chapters, we will be using a table called
test_users. You can find the SQL code to create and fill the table with test data below. Run it trough
your favorite MySQL client's SQL function, or use the command prompt to import into a new or
existing database.

First of all, let's create a new project for this in Visual Studio. Secondly, let's store the connection
information for the database in once place, so we can reuse all over our application. We will do this
with the web.config file. You can add it by right clicking the project name in the Solution Explorer, and
selecting "Add New Item". From the dialog that pops up, select "Web Configuration File". Press Add,
and the file will be added to your project. It will automatically be opened. Now, find the part that says
and replace it with this:

<connectionStrings>
<add name="MySQLConnStr" connectionString="DRIVER={MySQL ODBC 3.51
Driver};Database=YourDatabase;Server=localhost;UID=YourUsername;PWD=YourPassword;"/
>
</connectionStrings>

By doing so, we can access the connection string from all over the application. You should replace 3
values in it: YourDatabase, YourUsername and YourPassword. They should of course be replaced with
the name of the database that you care to use, as well as the username and password for one of the users
of the MySQL database server. In the next chapter, I will show you how we retrieve the value and use
it. It is important that you have some type of protection on your computer while doing this since you
can run across some corrupt documents. SafeNet Data Protection Company is one of the most
recommended businesses out there, they will make sure your computer is protected from malicious
files.

Here is the SQL code to create and fill our test table with some data:
CREATE TABLE `test_users` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(100) NOT NULL default '',
`country` varchar(100) NOT NULL default '',
PRIMARY KEY (`id`)
);

INSERT INTO `test_users` VALUES (1,'John','USA');


INSERT INTO `test_users` VALUES (2,'Mark','Canada');
INSERT INTO `test_users` VALUES (3,'Lukas','Germany');
INSERT INTO `test_users` VALUES (4,'Ingrid','Sweden');

MySQL - First access


Okay, let's try accessing our test table for the first time, using ASP.NET. First of all, we need to import
the System.Data.Odbc namespace. Add the following line in the top of your CodeBehind file:

using System.Data.Odbc;

This will give us access to a bunch of ODBC related classes. For now, we will need 3 of them:

OdbcConnection - Provides an ODBC connection to a database.


OdbcCommand - Will execute an SQL command using an existing OdbcConnection.
OdbcDataReader - Will provide fast access to the data which the OdbcCommand will bring us.

The first example will focus on getting access to our test data, and simply printing it out, and while this
is not how we normally do things with ASP.NET, it's simply meant to show you the most basic example
of data access. Since we write directly to the (top of the) page, we don't need to add any markup code.
Simply go to the CodeBehind (.cs) file, and add the following code to the Page_Load method:
try
{
using(OdbcConnection connection = new
OdbcConnection(ConfigurationManager.ConnectionStrings["MySQLConnStr"].ConnectionStr
ing))
{
connection.Open();
using(OdbcCommand command = new OdbcCommand("SELECT name FROM test_users",
connection))
using(OdbcDataReader dr = command.ExecuteReader())
{
while(dr.Read())
Response.Write(dr["name"].ToString() + "<br />");
dr.Close();
}
connection.Close();
}
}
catch(Exception ex)
{
Response.Write("An error occured: " + ex.Message);
}

Okay, if you come from the PHP world, you're probably about to run away because of the big amount
of code needed to perform a simple database extraction. However, C# is an Object Oriented language,
and sometimes it just takes a bit more code to make a more elegant solution. Of course, code like this
can be gathered in reusable classes and methods, but for now, we do it the basic way.

Now, let me try to explain the various lines of code. First we create an OdbcConnection object, to
establish the connection with the database. We use the ConfigurationManager class to obtain the
connection string which we stored in the web.config file in the previous chapter. It's with in a using()
construct, which is a convenint way to tell C# that when the block of code ends, it should dispose the
object. If we didn't use it, we would instead have to call connection.Dispose(); when we were done.
Next, we open the connection, and then we create an instance of the OdbcCommand class, which is
used to fire off SQL queries against the database. Using the command object, we query the database,
and in return we get an OdbcDataReader. The DataReader class is the simplest and fastest way to
access a database in .NET.

We loop through the datareader, and on each iteration, we output the name field from the database,
along with a linebreak tag. Pretty simple, right? As you can see, the entire data access block is
encapsulated in a try..catch block. Lots of things can go wrong when interacting with a database, so
using a try..catch block is recommended. Using dr["name"], we get the result as an object, which is
why I'm calling the ToString(). If you wish for more control of the datatype you receive from the
reader, you can use the Get* methods, like GetInt32(), GetString() etc. However, these methods require
you to use the index of the field in your query, and not the name of the field, which is not as
convenient.

Run the website, and have a look at the output. It should contain a bunch of names from our test table,
or which ever table you're using.

MySQL - Data Binding


Our first example was very little ASP.NET'ish. With ASP.NET, databinding is the big thing, and once
you've used it for a while, you will likely understand why. Databinding can really save some time for
you. We will start off with a very basic example of databinding, but even though it's simple, it's also
extremely useful. Populating a dropdown list can be a boring job, but have a look how easy it can be
done. Start off by adding a dropdown list to the page:
<asp:DropDownList runat="server" id="ddlUsers" datavaluefield="id"
datatextfield="name" />

The datavaluefield property tells the control which database field should be used for the value property
of each item, and the datatextfield tells the control which field to use for the actual text of the item.
That's all we need in the markup department, so switch to CodeBehind. Here we will use almost the
same code as in the last chapter, with a small modification:
try
{
using(OdbcConnection connection = new
OdbcConnection(ConfigurationManager.ConnectionStrings["MySQLConnStr"].ConnectionStr
ing))
{
connection.Open();
using(OdbcCommand command = new OdbcCommand("SELECT id, name FROM
test_users", connection))
using(OdbcDataReader dr = command.ExecuteReader())
{
ddlUsers.DataSource = dr;
ddlUsers.DataBind();
dr.Close();

}
connection.Close();
}
}
catch(Exception ex)
{
Response.Write("An error occured: " + ex.Message);
}

Only 2 things have changed from the last example: We've added a field to the query (the id field), and
we have changed the loop to a couple of databinding lines. The first one assigns the datasource of the
dropdown list to our datareader, and the second one tells the dropdown list to perform the databinding.
That's all we need, which you will see if you run the website. The dropdown list will be filled with
names from our test table.

This is just a basic example. Later on, when we work with repeaters, datagrids etc. you will surely
realize the true potential of databinding.

You might also like