You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.
Advertise
Best Hosting Service
Categories
- CMS Tools (1)
- Coding (6)
- CSS (13)
- Fonts (16)
- Freelance (16)
- Graphics (880)
- HTML (6)
- Icons (21)
- Illustrator (1)
- Inspiration (45)
- Interviews (8)
- IPhone (1)
- Java Script (4)
- Jquery (1)
- Logos (7)
- Marketing (5)
- Megento (1)
- Mobile Apps Development (2)
- News Letter (1)
- Photoshop (5)
- Resources (3)
- Responsive Design (2)
- Tutorials (4)
- Twitter (6)
- UI Design (1)
- UX Design (3)
- Wallpapers (7)
- Web Design (45)
- WordPress (23)
- Work (9)
Tags
3D
Artworks
brush
clients
Create
CSS
CSS3
design
designs
developers
Download free fonts
Fonts
Free
free fonts
Free Icons
Freelance
freelance websites
Graphics
Icon
Icons
Illustration
Illustrations
Illustrator
Inspiration
Inspirational
Interview
Javascript
Logos
Photo
photos
Photoshop
portfolio
Poster design
Texture
themes
tutorial
tutorials
Twitter
Typography
UI design
Vector
Web Design
Websites
WordPress
Wordpress Themes



ASP.NET for PHP Developers – Part II
In part one of the “ASP.NET for PHP Developers” tutorial, we learned the basics of ASP.NET and the C# language. Part
two builds on that foundation, and introduces some more advanced features and techniques to take your ASP.NET
pages to the next level.
Tutorial Details
Before you Start…
Ensure you have read and completed the examples in part 1 of the tutorial. We’ll be building on that application here.
It’s also worth stressing that you need a good grasp of object oriented programming (OOP) to continue.
And Before I Start…
I mentioned in part 1 of the tutorial that there are two flavours of ASP.NET available:
However I don’t use either of those, but rather a third approach of my own devising. That’s for several reasons:
runat="server"to HTML elements offered many of the advantages of true ASP.NET controls, but gave me full control over the HTML that was outputted. Things improved, and are looking even better for ASP.NET 4.0.javascript:__doPostBackfunction is a perfect way to make your website impossible to use for a large proportion of the web audience – oh, and search engines as well.So you can see why I chose this "roll-your-own" approach. As ASP.NET matured and I discovered new features, I started to integrate those into my applications, and I fully expect that over time I’ll be doing more of that.
So, let’s take our ASP.NET application to the next level.
Master Pages
My second favourite feature of ASP.NET (after turning HTML controls into server controls) is master pages. A master page is a template file you can use to encapsulate HTML you use in multiple pages. For example, your master page could contain the header, menu and footer of your pages, while your normal .aspx pages contain the actual content on that page. let’s look at an example web page:
You can see the parts which are used on multiple pages highlighted in green. The content which changes for each page in the site is highlighted in red. Master pages allow us to split up the code for these two sections into multiple files. If you’ve used templates in your PHP applications (for example WordPress has
header.php,footer.phpandsidebar.php) you’ll see how great master pages are.Creating a master page
So let’s create a master page. In the Solution view create a new directory in your ASP.NET application called "Master_Pages". In that directory create a new master page by right-clicking on the Master_Pages folder, selecting "Add > New file" then selecting "Master Page with Code Behind" and call it "DefaultMaster". Your new master page will be created and you’ll see the "DefaultMaster.master", "DefaultMaster.master.cs" and "DefaultMaster.master.designer.cs" files in the Master_Pages folder.
Open the "DefaultMaster.master" and "DefaultMaster.master.cs" files. The code-behind file (.cs) for the master page (.master) works exactly the same as the code-behind file for an .aspx page. The first thing to note is master pages do not inherit from System.Web.UI.Page like .aspx pages do. Instead they inherit from System.Web.UI.MasterPage. Here’s the default code for the code-behind.
using System; using System.Web; using System.Web.UI; namespace WebApplication1 { public partial class DefaultMaster : System.Web.UI.MasterPage { } }And for the .master file itself:
Because we’re not using the WebForms model, let’s quickly remove the tags for the
<form runat="server">element.You should be getting used to page declarations (the
<%@ Page ... %>bit in .aspx pages) by now, so the<%@ Master ... %>declaration will come as no surprise. What is different in this code is a new control:<asp:contentplaceholder>.This content placeholder is where the content from your .aspx pages will be inserted. You can have as many of these in a .master page as you like.
Referencing your master page
Let’s go back to our normal .aspx page and make some edits. The first thing to do is remove the
<html>,<head>and<body>tags, as they will now be in the master page. That leaves:Now we need to specify what content to place in the content placeholder. We do that by specifying where the master page is, and wrapping our content in an
asp:Contentcontrol, like this:There’s a couple of things to note here. Firstly the Page declaration has an additional attribute of "MasterPageFile" with a value of "~/Master_Pages/DefaultMaster.master". In ASP.NET "~" means the root of the application, the rest of that path just points to our master page.
Secondly you see the new
asp:Contentcontrol has an attribute of "ContentPlaceHolderID" with a value of "contentPlaceHolder", which is the "id" attribute of our<asp:contentplaceholder>. Running the application will give you:Checking the source code of the page proves that the master page (.master) and content page (.aspx) have been seamlessly integrated together. Now you see why I love master pages so much.
A more complex master page
We can push master pages a lot further than this simple example. Let’s have a go at building something that looks more like a real web application, starting with the master page. Firstly we’ll add some more content placeholders and a few server-side controls:
And in the code-behind file for our master page we’ll put:
using System; using System.Web; using System.Web.UI; using System.Configuration; namespace WebApplication1 { public partial class DefaultMaster : System.Web.UI.MasterPage { protected void Page_Load(object sender, EventArgs e) { sitename.InnerHtml = ConfigurationSettings.AppSettings["SiteName"]; copyright.InnerHtml = ConfigurationSettings.AppSettings["CopyrightNotice"] + DateTime.Now.Year.ToString(); } } }(I’ll leave it as an exercise for you to add the SiteName and CopyrightNotice applications settings to web.config.)
Now for our content page. We have four content placeholders we can use: PageTitle, PageJS, PageCSS and PageContent. Here’s the code for the .aspx content page:
<%@ Page Language="C#" MasterPageFile="~/Master_Pages/DefaultMaster.master" Inherits="WebApplication1.Default" %> <asp:Content id="PageTitle" ContentPlaceHolderID="PageTitle" runat="server"> <asp:Literal id="Title" runat="server"></asp:Literal> </asp:Content> <asp:Content id="PageCSS" ContentPlaceHolderID="PageCSS" runat="server"> <style type="text/css"> h1 { font-family: sans-serif; color: #090; } </style> </asp:Content> <asp:Content id="PageContent" ContentPlaceHolderID="PageContent" runat="server"> <h2>Welcome, one and all</h2> <p>This is my very first ASP.NET website, working with a master page!</p> </asp:Content>And the code-behind for our .aspx content page:
using System; using System.Web; using System.Web.UI; using System.Configuration; namespace WebApplication1 { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Title.Text = "Welcome to my first ASP.NET Website"; } } }A couple of new things to notice here. Firstly I haven’t used the PageJS content placeholder at all – it’s quite OK to leave it out entirely (of course nothing will be rendered to the page for that area). Secondly I’ve introduced another ASP.NET control, namely
<asp:Literal>, which we’ll take a quick look at now.The Literal control
The Literal control is very useful when you want to render something to the page without any extra markup. For example, a lot of the time it’s fine to use:
Gives:
But if you don’t want the span tags at all, for example for the page
<title>, you need the Literal control. Setting the "Text" property of the Literal control renders just that text to the page:Gives:
The completed master and content page
So running our application should give us this:
This is really just scratching the surface, as it’s possible to have multiple master pages (even nested master pages!). You can also set the master page programatically (but this needs to be done in the Page_Init event, as Page_Load is too late in the page lifecycle). There’s lots more detail about MasterPages on the MSDN site.
Custom Classes
It’s possible to create custom classes in your application, just like you would in PHP. Let’s create a security class by right-clicking the root of your application and selecting "Add > New file" then choosing "Empty class" from the "General" section and calling it "Security".
The code for your new class looks like this:
using System; namespace WebApplication1 { public class Security { public Security() { } } }I’ll throw a bit more code into this file:
using System; using System.Web; namespace WebApplication1 { public class Security { public bool IsLoggedIn; public Security() { CheckSession(); } private void CheckSession() { if (HttpContext.Current.Session["loggedin"] != null && HttpContext.Current.Session["loggedin"] == "true") { IsLoggedIn = true; } else { IsLoggedIn = false; } } } }Pretty simple so far. The only new thing is the use of
HttpContext.Current.Sessionrather than justSession, that’s becauseHttpContext.Currentis implicit in an .aspx web page, but not in a standalone class.In our Default.aspx.cs code-behind file we write:
protected void Page_Load(object sender, EventArgs e) { Security security = new Security(); if (security.IsLoggedIn) { Title.Text = "Welcome back, you are logged in"; } else { Title.Text = "You are not logged in"; } }Which instantiates a new instance of the Security class names "security". Running the application shows this:
As you’re familiar with OOP you can see how this can be used to build large-scale web applications. The only other thing to say about custom classes is how to make them static. Here’s the code for a static class:
using System; using System.Web; namespace WebApplication1 { public static class Security { public static bool IsLoggedIn; public static void CheckSession() { if (HttpContext.Current.Session["loggedin"] != null && HttpContext.Current.Session["loggedin"] == "true") { IsLoggedIn = true; } else { IsLoggedIn = false; } } } }You can see there’s no default method, as this class is never instantiated. I’ve also added the "static" keyword to the property and method, and I’ve made the
CheckSession()method public. To use this static class we would write:protected void Page_Load(object sender, EventArgs e) { Security.CheckSession(); if (Security.IsLoggedIn) { Title.Text = "Welcome back, you are logged in"; } else { Title.Text = "You are not logged in"; } }Pretty simple, really. As you’re fully aware of the advantages that OOP can give you for abstraction, encapsulation and inheritance you’ll see how powerful this is. But if we’re going to use objects, we really need some serious data to model in our objects. We need a database.
Databases, Data Sources and Data Binding
ASP.NET works really well with databases, but works the best with Microsoft SQL Server (not surprisingly). Even if your ASP.NET application is running on a Linux box, you can still connect to SQL Server on a Windows server to use as a datastore. I’ll demonstrate that below, but as I’m writing this tutorial in Linux I will also demonstrate the use of MySQL as an ASP.NET database. To use MySQL you’ll need the ADO.NET driver for MySQL – this excellent article helped me a lot.
Database configuration
The first thing to do is configure how to connect to our database server. You can do this in web.config, add this code inside the "configuration" section (the MySQL and SQL Server code should be pretty obvious). Note that these are standard connection strings.
I’ve also created a table called "users" with this code (this is for MySQL, minor edits will make it work in most other database systems):
To access your connection string you can use the ConfigurationManager class which we used in part 1 of the tutorial to access global configuration settings. Here’s the code:
Connecting and running a simple query
So we’re now ready to connect to our database and run a query. First, insert a couple of rows into the " users" table so we have something to query:
insert into users (username, password, email) values ('User 1', 'user1password', 'user1@asp.net')We then need to ensure we reference the right assemblies. For MySQL make sure you have this at the top of your code-behind file:
Amd for SQL Server use this:
A quick note about connecting to MySQL in Linux. I had a bit of trouble making my application compile when I first tried this. I did various searches but found no answer that worked for me. The error I got was "The type or namespace name `MySqlConnection’ could not be found." which looked like the MySQL Connector wasn’t installed properly. The fix (for me) was to manually add the reference by right-clicking the References folder in my application and going to "Edit references". I then found the MySQL.Data.dll file in the .Net Assembly tab and referenced it. I also had to then manually reference the System.Data and System.Configuration assemblies from the Packages tab.
Hopefully you won’t need to jump through these hoops.
We now open a connection to our database like this for MySQL:
protected void Page_Load(object sender, EventArgs e) { // get the connection string string conn = ConfigurationManager.ConnectionStrings["MySQL"].ConnectionString; // create a new MySQL connection MySqlConnection dbcon; using (dbcon = new MySqlConnection(conn)) { // open the connection dbcon.Open(); // create the query string query = "SELECT username, email FROM users"; // create a new adapter between the connection and query MySqlDataAdapter adapter = new MySqlDataAdapter(query, dbcon); // create a new dataset to store the query results DataSet ds = new DataSet(); // fill the dataset with the results from the adapter, // the name of the dataset is "result" adapter.Fill(ds, "result"); } }And this for SQL Server:
protected void Page_Load(object sender, EventArgs e) { // get the connection string string conn = ConfigurationManager.ConnectionStrings["SQLServer"].ConnectionString; // create a new SQL Server connection SqlConnection dbcon; using (dbcon = new SqlConnection(conn)) { // open the connection dbcon.Open(); // create the query string query = "SELECT username, email FROM users"; // create a new adapter between the connection and query SqlDataAdapter adapter = new SqlDataAdapter(query, dbcon); // create a new dataset to store the query results DataSet ds = new DataSet(); // fill the dataset with the results from the adapter, // the name of the dataset is "result" adapter.Fill(ds, "result"); } }See, pretty easy, and not a million miles away from the equivalent PHP code. There are a couple of bits in here I’ll explain in some more depth. Firstly the
usingstatement:using (something here) { ... }The object you set up in the brackets is automatically destroyed when your code leaves the end curly brace "}". This is a really useful structure to know about, so read all about it here.
Secondly the
DataSet. In the code above the results from the database query are fed into a DataSet, which is an object containing one or more tables, each table containing rows and columns. That means you can do useful things like:And there are many other goodies in the DataSet class. You can also loop rows, just like you do in PHP, like this:
for (int x = 0; x < ds.Tables[0].Rows.Count; x++) { Response.Write(ds.Tables[0].Rows[x]["fieldname"].ToString() + <br />); }But there’s a much better way to display simple loops, and that’s using the Repeater control.
Using repeaters and databinding
First a confession. There are large ASP.NET applications I’ve written that use no ASP.NET controls except the Literal (which we looked at above) and the Repeater. The Repeater control allows you to "bind" data, for example from a DataSet, and display it in a looped manner. Firstly we need to add something to our database code above:
protected void Page_Load(object sender, EventArgs e) { // get the connection string string conn = ConfigurationManager.ConnectionStrings["MySQL"].ConnectionString; // create a new MySQL connection MySqlConnection dbcon; using (dbcon = new MySqlConnection(conn)) { // open the connection dbcon.Open(); // create the query string query = "SELECT username, email FROM users"; // create a new adapter between the connection and query MySqlDataAdapter adapter = new MySqlDataAdapter(query, dbcon); // create a new dataset to store the query results DataSet ds = new DataSet(); // fill the dataset with the results from the adapter, // the name of the dataset is "result" adapter.Fill(ds, "result"); // below is the new code... // set the DataSource of the repeater myRepeater.DataSource = ds; // bind the data myRepeater.DataBind(); } }And in the .aspx page we put:
<asp:Repeater id="myRepeater" runat="server"> <HeaderTemplate> <table> <tr> <th>Username</th> <th>Email</th> </tr> </HeaderTemplate> <ItemTemplate> <tr> <td><%# Eval("username") %></td> <td><%# Eval("email") %></td> </tr> </ItemTemplate> <AlternatingItemTemplate> <tr class="alt"> <td><%# Eval("username") %></td> <td><%# Eval("email") %></td> </tr> </AlternatingItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater>You can see what happens here. When the data is bound to the Repeater control the HeaderTemplate section is displayed. Then each row is displayed in the ItemTemplate and AlternatingItemTemplate sections (the names should give you a clue how they are displayed). Then finally the FooterTemplate section is displayed. Using this simple control gives you an easy way to display repeating data, with complete control over the resulting HTML – just like you would do in PHP. Here’s the results (with some CSS for styling):
As a Repeater will throw an Exception if an empty DataSet is bound to it, you need to check there is data to be bound first. A simple
ifstatement will work, checking if there are tables in the DataSet and if the first table has rows:if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { myRepeater.DataSource = ds; myRepeater.DataBind(); }I think you’ll agree that having a control which sets templating for repeating data as easily as that is a massive help to the developer. One thing to note with the Repeater control – if you bind a DataSet to it by default the first table is used. If you’re using stored procedures instead of inline SQL to run commands against your database you can return multiple tables, meaning you can load several sets of data for use in a page at once. In that case you’d use code like this (to bind the second table in the DataSet to the Repeater):
Creating a data access class
Let’s pull the last couple of sections together and create a data access class that will simplify connecting to and running commands on your database. This code is for MySQL, but as you’ve seen the code for SQL Server is very similar. Create a new empty class called "DB" and paste this into the new file:
using System; using System.Configuration; using System.Data; using MySql.Data.MySqlClient; namespace WebApplication1 { public class DB { private string ConnectionString; public DB() { // get the connection string this.ConnectionString = ConfigurationManager.ConnectionStrings["MySQL"].ConnectionString; } public DataSet Select(string query) { MySqlConnection dbcon; using (dbcon = new MySqlConnection(this.ConnectionString)) { // open the connection dbcon.Open(); // create a new adapter between the connection and query MySqlDataAdapter adapter = new MySqlDataAdapter(query, dbcon); // create a new dataset to store the query results DataSet ds = new DataSet(); // fill the dataset with the results from the adapter, adapter.Fill(ds, "result"); // return the dataset return ds; } } public bool Execute(string query) { MySqlConnection dbcon; using (dbcon = new MySqlConnection(this.ConnectionString)) { // create a new SQL command on thie connection MySqlCommand command = new MySqlCommand(query, dbcon); // open the connection dbcon.Open(); // execute the query and return the number of affected rows int affectedrows = command.ExecuteNonQuery(); // there were no rows affected - the command failed if (affectedrows == 0) { return false; // the command affected at least one row } else { return true; } } } } }To use this in your code-behind file you’d put:
DB db = new DB(); DataSet ds = db.Select("SELECT username, email FROM users"); if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { myRepeater.DataSource = ds; myRepeater.DataBind(); }This data access class introduces you to a new style of database connection syntax using the MySqlCommand class (SqlCommand for SQL Server) and the ExecuteNonQuery method. As the code says, the ExecuteNonQuery method executes a query and returns the number of affected rows. Very useful for
INSERT,UPDATEandDELETEcommands.Those of you with a good knowledge of WordPress will see how this class is similar to the
$wpdbglobal class in WP which offers methods like$wpdb->get_results("select * from table");and$wpdb->query("delete * from table");. It would be easy for you to extend this data access class to have more useful properties and methods for your applications.User Controls
So far we’ve used just two ASP.NET controls – Literal and Repeater – in honour of our aim to keep full control of the output HTML. But sometimes it’s useful to encapsulate functionality for your own controls. ASP.NET allows you to create user controls with properties and methods all your own. These user controls can be thought of as discrete blocks of HTML that can be used inside a .aspx page, just like you’d include a separate file in a .php file.
We’re going to create a very simple control that displays a truncated link. Firstly add a new file of type "User control with code-behind file" and call it "ShortLink".
You may notice the new file has an extension of .ascx, this is the extension for user controls. Open the .ascx file and you’ll see this:
Open the code-behind file (MyControl.ascx.cs) and you’ll see this:
using System; using System.Web; using System.Web.UI; namespace WebApplication1 { public partial class MyControl : System.Web.UI.UserControl { } }Continue Learning…
Related Posts