This tutorial, for PHP developers, will provide you with an introduction to ASP.NETusing the C# language.
If you've wondered what ASP.NET is about, this tutorial will strive to answer at least some of your questions. Even if you're an ardent open-source fan, ASP.NET contains some techniques and features that are useful to know about. And, as some might say, it's good to know your enemy!
Before you Start
ASP.NET is no longer a Microsoft-only technology. Thanks to the hard work of the Mono project contributors, ASP.NET can be used on Linux and Mac platforms, as well as Windows.
They've even created an IDE within which you can write your web and desktop applications. Download a copy of MonoDevelop and install it. We'll be using that IDE for this tutorial, as it offers some useful features to speed up development time. However, just like PHP, ASP.NET applications can be written in nothing more complex than a text editor.
ASP.NET and C# at a Glance
ASP.NET is Microsoft's web development technology framework, and was originally designed as a replacement for the old Active Server Pages technology. If you've used classic ASP (normally using VBScript) you'll find parts of ASP.NET very familiar. ASP.NET can be used with a wide range of programming languages, including VB.NET (the new version of Visual Basic), J# and C#. This tutorial will be using C#.
ASP.NET is available in two flavours:
- ASP.NET WebForms: the original framework allowing developers to create web applications using many of the same techniques used in .NET Windows desktop applications
- ASP.NET MVC: a newer framework offering Model-View-Controller architecture and more control over client-side code
As this tutorial is aimed at PHP developers, who a lot of the time prefer to get "closer to the metal," I won't be using either of these. Instead, I'll be rolling my own application based on the features of the .NET runtime and C# languages, withASP.NET as a wrapper, rather than a framework as it was intended to be. Don't worry if that doesn't make sense, just continue with the tutorial and you'll see what I mean.
I'm also running MonoDevelop in Xubuntu Linux, but it should work the same on other platforms.
Important: ASP.NET is very much built on object-oriented programming (OOP). If you have no experience with OOP I strongly suggest you read this introduction to OOP in PHP. You'll need to understand words like "class", "instance", "method", "property" and "inherit".
Five Things to Watch Out For
C# can confuse PHP developers, especially if you switch between the two languages on a regular basis. Here's my top five gotchas.
In C# string concatenation is done with "+" rather than ".".
"This is part 1 " . "and this is part 2!";
"This is part 1 " + "and this is part 2!";
Referencing class methods and properties
To call a method or property in PHP you'd use:
$myclass = new MyClass();
$var = $myclass->var;
In C# you use a "." instead of "->", like this:
MyClass myclass = new MyClass();
string var = myclass.var;
C# is a strongly-typed language, so you can't, for example, just treat strings as integers like you can in PHP. In PHP, this is true:
In C# it would cause an error. You need to convert one of the elements:
You'll find yourself using that
.ToString() method a lot...
Methods return types
With PHP, the type of the return value of a function or method doesn't matter. In C# methods must declare the type of value they return:
Methods that don't return anything must have the void keyword:
Watch out for the scope of methods and properties. The three important keywords are "public", "protected" and "private". These work the same as they do in PHP.
Creating your first ASP.NET Page
Choose "Start a New Solution" in the main screen. A "solution" is a collection of one or more related projects. They can be projects of different types, for example a web application and a desktop application that works with it, and perhaps a web service as well.
Select C# ASP.NET Web Application, type a name for your application (I'm using "WebApplication1") and choose a location for your solution then click "Forward". Ignoring the options on the next page, click "OK" and a new ASP.NET application will be created at the location you specified.
The IDE will open the default page, called "Default.aspx" and you'll see the following code:
You'll see it's mostly standard HTML, with a few extra bits. There's already a
<form>element with a strange
<asp:Button> element inside it. Let's try running the application.
Running your Application in Debug Mode
MonoDevelop can run your ASP.NET application with one button. Rather than having to set up a local development server and configure your app, simple press F5. A development server will be launched on a non-standard port and you'll see your application open in a browser. Note port
8080 in the URLs below.
Note: In Xubuntu I had to manually install the Mono web server named XSP2 with this command:
sudo apt-get install mono-xsp2.
So, press F5 to run the application, you'll hopefully see a browser window open that looks like this.
Clicking the button shows this.
What you've just done is clicked an ASP.NET button, which automatically wires-up events to server-side code. In other words, when the button is clicked the page knows about it - this is one of the main advantages of the WebForms framework, it works much like desktop application development. But we're not going to use this feature as it leads to a world of pain (which is explained in Part 2 of this tutorial). Instead we're going to do things a little more manually. It's the PHP way.
So, we're going to change this code slightly as we don't want to use the WebForms framework. Edit the opened "Default.aspx" by removing the
<form> element and adding a
<h1> element so the code is:
<%@ Page Language="C#" Inherits="WebApplication1.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<h1>This is the text</h1>
Browsing your Solution
On the left hand side of the IDE there are three views of the application. The first view is Classes, and shows the class diagram of the application.
The second view is Solution, and shows the projects and files which comprise the entire solution (you can have multiple projects in a solution).
And there's also a Files view which shows you all the directories and files in the solution, including the "WebApplication1.csproj" file which is the C# project file for our application.
Choose the Solution view. You've already got "Default.aspx" open, which is the page you've just edited. Double-click the file called "Default.aspx.cs" to open it in the IDE. Here's the first important lesson.
The neat thing is these code-behind files are automatically included in your .aspx page. (That's why the code-behind is called "Default.aspx.cs", so it is associated with the "Default.aspx" file.) The code of "Default.aspx.cs" is pretty short. Here's an explanation, line-by-line:
A Note About Namespaces
Wikipedia defines a namespace as:
a namespace is an abstract container providing context for the items (names, or technical terms, or words) it holds and allowing disambiguation of homonym items having the same name (residing in different namespaces)
Which is pretty complicated. I mean, homonym? I see namespaces as virtual directories for classes. Just as in a file system you can't have two files called "test.txt" in the same folder, you can't have two classes with the same name in a single namespace. Namespaces can be nested, just like directories (hence the
System.Web.UI references in the code above) and have to be referenced from your ASP.NET code-behind files so you can use the classes contained in them.
You'll also have noticed that our application is in the namespace WebApplication1, which means any code we write is within that namespace. We'll use that to our advantage later on.
A Note About Pages
In ASP.NET, a web page is actually a class. It belongs in a namespace in a project, and inherits from the
System.Web.UI.Page class. In the code-behind file this is expressed as:
(The "Partial" keyword means that part of this class is also in another file, namely the "Default.aspx.designer.cs" file. As that file is automatically-created and maintained we don't need to worry about it.)
Your "Default.aspx" inherits from the page we've just created, using this code:
<%@ Page Language="C#" Inherits="WebApplication1.Default" %>
In the "Page" declaration we're setting the language for the page and the class it inherits from, in this case
WebApplication1.Default. That means that if we create another page, for example "Contact.aspx", the "Page" declaration and code-behind file would be:
// .aspx page
<%@ Page Language="C#" Inherits="WebApplication1.Contact" %>
This can be hard to get your head round to start with, but by the time you've created a few pages it will be second nature.
Creating Some Custom Functionality
We're now ready to write something ourselves. Remove the "button1Clicked" method and in it's place add the following code:
The "Page_Load" method is one of several life-cycle events that get automatically called when the page's Load event fires. There are quite a few events that happen in the life-cycle of an ASP.NET page, see the full list here. Generally the "Page_Load" method is where you put anything you want to happen when that page is loaded (security checks, fetching data from a database for display, loading an advert etc.). We're going to declare a new method for the page called "SetText" which is called from the "Page_Load" method;
You can guess this sets the "InnerHtml" property on the element "headertext" to "This is the changed text". But what is "headertext"? Go back to "Default.aspx" and modify the
<h1> element to this:
Then press F5 to run the application. If everything works OK you should see this:
Check the source of the page. You'll see the
runat="server" attribute has gone. What just happened? We turned an HTML control into a server-side control, that's what.
My favourite feature of ASP.NET by far is the ability to turn almost any standard HTML control (elements are also known as controls) into a server-side control. This means that ASP.NET knows what the control is, and can change its properties and run methods on it from the code-behind page. In our example above, the
<h1>element had two attributes added:
<h1 id="headertext" runat="server">This is the text</h1>
Now in our code-behind file ("Default.aspx.cs") we could access the control and change its properties.
One of the best features of using an IDE such as MonoDevelop rather than a text editor is Intellisense, which gives you a menu of options as you type. Properties of objects, system classes and methods, custom classes and methods, it's all there:
(I believe "Intellisense" may be a Microsoft trademark, but I'm unsure what MonoDevelop call it!)
There are loads of other properties available for different controls (for example an
input type="text" control has a "value" property), and they all appear in a list as you type. There's also a massively useful property called
Visible. This sets whether the control is visible in the source. Look at this example:
<div id="notloggedin" runat="server">
<h1>You are not logged in</h1>
<p>Please <a href="/login">log in to the site here</a>.</p>
<div id="loggedin" runat="server" visible="false">
<h1>Thanks, you've logged in</h1>
<p>Welcome back, user!</p>
Notice I've manually added the
visible="false" for the
loggedin element. When used with this server-side code we can make each
<div> control visible or invisible.
You can imagine how easy that makes configuration of pages, and how much cleaner your code can be.
How about form elements? Let's make a
<select> control server-side:
<select name="genre" id="genre" runat="server">
Selecting a particular option is as easy as this:
Told you you'd use the
ToString() method a lot. The
Itemsproperty also has a useful method called
FindByText() which does this:
Intellisense will even give you a list of controls it finds, so you don't even need to remember what you called all those different text boxes. As we're using normal HTML controls converted to be server-side (rather than true ASP.NET controls) we lose some functionality, but nothing we can't live without. In Part 2 of the tutorial we'll be using a true ASP.NET control. But first, a word about configuration.
The Web.config File
In your PHP applications you have not doubt had a configuration file named "config.php" or similar. ASP.NET has a special file type for configuration files called ".config" which are automatically disabled from public view. Your ASP.NETapplication already has a "Web.config" file, open it from the Solution view in MonoDevelop.
You'll see it's a standard XML file. We're going to add some application-wide settings, so edit the file adding this code just above </configuration>
<add key="ApplicationName" value="My first ASP.NET Application"/>
<add key="Developer" value="Chris Taylor"/>
Going back to our "Default.aspx.cs" file we reference the
And we can now access our "ApplicationName" setting using:
So to jazz things up a bit, let's try:
F5 to run the application and you'll see:
As you'll appreciate, this gives you a huge amount of power over site-wide settings.
Sessions, Cookies and Post/Get Parameters
You can't get very far developing web applications without dealing with Sessions, Cookies and Post or Get parameters. ASP.NET handles these pretty well, with a couple of gotchas.
To get the session ID use:
Session.SessionID. Warning: if you don't store anything in the session the SessionID property *may* change on every page request. Yes, I know, it's madness. The fix is to store something in the session.
To store something in the session use:
Session["var"] = "value";.
To retrieve something from the session use:
string value = Session["var"];.
To store something in a cookie use:
Response.Cookies["name"].Value = "value";.
To retrieve something from a cookie use:
string value = Request.Cookies["name"].Value;.
Note the different use of
Response and the fact you have to set the
Value property. You can also set other properties of each cookie (check Intellisense for full details):
In that last example you got your first look at the
DateTime class. This, in a word, is fantastic. Although it lacks the "numbery-ness" of PHPs
time() function, it provides a massive array of chainable methods to create and modify datetimes. This is a good introductory article.
These are contained, like cookies, in the
Request object. That object contains loads of stuff useful for application developers, and can be roughly compared with PHPs
$_SERVER variable. Here are a few other useful things:
For a full list of
Request.ServerVariables this is a good resource.
Getting back to the point; to retrieve something from a post parameter (submitted by a form) use:
string value = Request.Form["param"];.
And to retrieve something from a get parameter (in the querystring) use:
string value = Request.QueryString["param"];.
For session variables, cookies, and post and get properties, always check the parameter is not null before trying to access it. This is the equivalent of PHPs
isset() function. C# is very unforgiving when it comes to null objects, so in general it always pays to check something exists before trying to use it.
You can also put multiple parts in an if statement. So to check if the user has a cookie with the name "loggedin" with the value "true", this will work:
Just like PHP, if the first part of the if statement fails the second one is not run.
Here's a table of common code snippets in PHP with their equivalents in C#.
Click image to view at full size.