Boost Performance by Using a CDN in Your ASP.NET Site

A CDN (Content Delivery Network) is simply a network of data centers spread across the globe which serve static content to a user from the nearest available data center. Thus a request for a static file by a user in Australia
would be served from a nearby AsiaPac data center instead of the US (where the main site may to served from). This reduces the latency and therefore boosts performance.

A secondary factor boosting performance is that typically browsers can only open up 2 simultaneous connects to a host, therefore if your web page will require 20 file requests and all static files are on the same server the requests are
queued two at a time. If a CDN is used, the browser can open up more simultaneous file requests and so boost performance.

Which CDN ?

There are numerous CDNs to choose from, personally I use the Rackspace CloudFiles. Rackspace recently partnered with Akamai and so the CDN network is top notch – although the tools are quite weak. It is not possible to FTP a file
to a CDN but the FireUploader utility for Firefox is satisfactory (note that this had some issues with Firefox 4.0 when I tested it and as such I am still using it with Firefox 3.6).

I won’t list all available CDN options as I have not tried that many, but I also had a good experience with MaxCDN, although their pricing structure is quite unusual and so you should carefully examine this to guage your costs.

One thing to note, Amazon’s S3 storage solution is NOT a CDN. All files served from S3 are served from a single location and not from an array of data centers.  Amazon does have a CDN offering – CloudFront, however I would not recommend this as it did not perform well in any of my testing. The Azure CDN offering had a similar performance to the CloudFront product in my experience and so I wouldn’t recommend it.

How to Use a CDN

Using a CDN is very simple, just upload your static files to the CDN and then set the src attribute of the element (such as an <img> tag).

When a file is requested for the first time it will first be served from the central data center and then cached at the edge location (ie worldwide data center nearest to the requesting user). All subsequent requests will be served from the cache of the edge location until the TTL (Time To Live) value has expired. This can be a gotcha if you are updating the files. This typically happens a lot with css files. Therefore if you update your site’s css file, then upload it to your CDN, site users around the worldwide may be served a cached version of the old file. To get around this you can specify version numbers for your css files, in this way each file is unique and when you push an update the CDN will request the new css file from the central store before caching it.
By way of example if you look at the source for this SharePoint article you will see that most of the static files are served from a CDN.

Free SQL Server Backup Script

The SQL Server backup function accessible from SQL Server Management Studio is convenient but crude, the powerful script allows for backing up multiple databases and setting many other parameters such as compression, verification etc. [].

Including ASP.NET Membership in an Existing Database

By default, when adding ASP.NET Membership to your web app a new ASP.NET Membership database will be created. However, in many circumstances you may wish the Membership database to be part of your  main application database. To do this simply navigate to \Windows\Microsoft.NET\Framework\v2.0.50727 (use this path even if you are using ASP.NET 4.0 in your application as the Membership database has not changed since ASP.NET 2).

Then find and run the aspnet_regsql.exe program. This will bring up a dialog allowing you to specify the target database to incorporate the ASP.NET Membership tables and stored procedures :

ASP.NET Membership database inclusion dialog

The final step is to ensure that the all connection string references to the membership provider in the web.config point to this database. Don’t forget if you are using Roles that the role provider specified in the web.config must also point to this database (otherwise ASP.NET will automatically create a new database for the roles when the app is run).

ASP.NET MVC Authentication using AccountController

The AccountController class is a controller for user authentication which is included in a default MVC project created with Visual Studio. Prior to using this controller, you will need to modify it so that it no longer refers to the HomeController which you most likely will remove. To do this, replace each of these instances:

return RedirectToAction("Index", "Home");

so they are as below:

return RedirectToAction("Index", "Products");

This will cause the authentication controller to redirect a user to the products controller once an authentication action ends. The default ASP.NET MVC master page has links for a  user to log in/out and register. The MVC Authorize filter facilitates control over which users may access the controller methods. Below is an example of the Authorize filter being  applied to the Delete method in the products controller class:

public ActionResult Delete(int id) {
NorthwindEntities dbObj = new NorthwindEntities();
var data = dbObj.Products.Where(e => e.ProductID == id).Select(e => e).Single();
return View(data);

If a user clicks a delete link to delete a record of a product, the MVC framework is then checked. If the user is currently logged in, the action will proceed.. If the user has not logged in they will then be requested to provide their username and password credentials or else to create a new account. This can be made even more restrictive by specifying user names as part of the filter. Below is an example of the Authorize filter applied so the Delete method is only available to Mike Smith:

[Authorize(Users="Mike Smith")]
public ActionResult Delete(int id) {

Now only Mike Smith can perform the delete actions, all other users will be asked for their credentials. The MVC Authorize filter can even be applied to the whole controller class. Below is an example of the Authorize filter being applied to the ProductsController class, so that only authenticated users can access controller actions:

public class ProductsController : Controller {

The Authorize filter has an Order property which works just as the HandleError Order property. If the  Authorize filter is applied for the whole controller level and for a specific action method, the controller-wide setting will always have precedence unless the Order property is used.

Sending Mail from a .NET App Using Amazon SES (Simple Email Service)

Amazon’s Simple Email Service (SES) is a great solution for any project which requires bulk emails. the primary advantage of SES is cost, at $0.10 per 1000 emails sent it is between 5-10x cheaper than other alternatives such as SendGrid. There is a downside to the SES service, however and it is that it currently doesn’t provide an SMTP wrapper so whilst SendGrid and others allow you to simple change your SMTP settings, with SES you will have to do a bit more work.

Amazon (AWS) provides a very useful .NET SDK (complete with dll’s for .NET 2.0, 3.5 and 4.0) which you can simply copy into your project and start calling the Amazon functions from a .NET app such as an ASP.NET site. You can download the SDK here.

The below code shows a simple example of how to use the Amazon AWS SDK in .NET to send emails.

Dim listColl As New System.Collections.Generic.List(Of String)
'//TODO - Write a simple loop to add the recipents email addresses to the listColl object.

Dim client As New Amazon.SimpleEmail.AmazonSimpleEmailServiceClient("aws_public_key_here", "aws_private_key_here")

Dim mailObj As New SendEmailRequest
Dim destinationObj As New Destination(listColl)
mailObj.Source = ""  '//The from email address
mailObj.ReturnPath = "" '//The email address for bounces
mailObj.Destination = destinationObj

'//Create Message
Dim emailSubjectObj As New Amazon.SimpleEmail.Model.Content("This is the Subject")
Dim emailBodyContentObj As New Amazon.SimpleEmail.Model.Content("This is the Body<br /><em>In Html</em>")

Dim emailBodyObj As New Amazon.SimpleEmail.Model.Body()
emailBodyObj.Html = emailBodyContentObj
Dim emailMessageObj As New Message(emailSubjectObj, emailBodyObj)
mailObj.Message = emailMessageObj

Dim response = client.SendEmail(mailObj)

That’s it, there’s really not a lot of heavy lifting to get starting using SES with .NET. the only thing I didn’t show in the code above is the loop for adding email addresses as strings to the generic collection, this loop will vary a lot depending on your exact requirements.
One thing to note above is that you will need to import the namespace Amazon.SimpleEmail.Model

AWS SES is not as full featured as a lot of solutions such as SendGrid, however it does have several useful features out-of-the-box such as the ability to perform email validation:

Dim testEmail As String = ""

Dim verRequest As New VerifyEmailAddressRequest()
verRequest.EmailAddress = testEmail

This should get you going with SES, I will update this page once the service develops.