Deploying Your Website - Beginning Visual Basic (2012)

Beginning Visual Basic(2012)

Chapter 19

Deploying Your Website

What You Will Learn in This Chapter:

· How to ease the deployment process through simple changes to your code and configuration

· How to prepare your site for deployment by creating a copy using Visual Studio's built-in copy tools

· How to install and configure a web server and your website on your target machine

· How to avoid common errors you may get when deploying a site

· How to copy data stored in your SQL Server database to the target server Code Downloads for this Chapter

You can find the code downloads for this chapter on the Download Code tab at The code is in the Chapter 19 download.

Congratulations! The fact that you're reading this chapter probably means you now have a full-featured, database-driven ASP.NET website that is ready for release into the wild. It's an exciting time for you and your project. Pretty soon your application will be used and judged by your target audience.

To make your website accessible to users worldwide, you need to publish it to a production server that is connected to the Internet. What kind of server this is and where it is located depends on your own requirements and budget. You can host the site on a home server in your attic with a private Internet connection (as I used to do with or you can host it with an external (and often commercial) party with a direct connection to the Internet backbone.

Either way, you need to do some work to get your site from its development location at C:\BegASPNET\Site to a location where it's accessible over the Internet.

This chapter deals with a few topics related to successfully deploying your website. You learn about the process from preparing your site in the development environment to actually running and testing it at your production server.

The chapter then ends with a list of things you need to take care of when deploying your site. You can use this checklist to make sure you configure your production site in the most secure and optimal way.

Preparing Your Website for Deployment

When you're working on the first edition of your website in a development environment, managing the site and its source code is pretty straightforward. You have only a single version of the site's source, making it easy to maintain. However, as soon as you put your site in production, you now have two versions of it: one running in the production environment and the one you use for development. This makes it difficult to keep things synchronized. For example, you probably use a different database and connection string in your production environment. You're also likely to use different e-mail addresses for the e-mail that is sent by the site. Finally, you may want to disable sending the error e-mails from the Global.asax files in a development environment. If you make all of these changes in the code directly when you put your site on a production server, there's a fair chance that you'll overwrite some settings during the next update, which can lead to unwanted results.

This section shows you how to make managing different versions of the same website a little easier. You see how to move some of the hardcoded settings, such as e-mail addresses, to the Web.config file. The code in your application then reads these values at run time. The only difference between your development and production environments is then a single configuration file, making it easy to have different settings in both environments.

Avoiding Hard-Coded Settings

So far, the pages and user controls you have built use some hard-coded settings for things like e-mail addresses. For example, ContactForm.ascx, the user control that sends out an e-mail, uses the following code to set the recipient and sender information:


myMessage.From = New MailAddress("", "Planet Wrox")
myMessage.To.Add(New MailAddress("", "Planet Wrox"))


myMessage.From = New MailAddress("", "Planet Wrox");
myMessage.To.Add(New MailAddress("", "Planet Wrox"));

Hard-coding settings in this manner makes it difficult to give them different values in different environments. Every time you want to roll out your site to production, you need to make sure you're not accidentally overwriting settings you changed for the production environment.

Fortunately, ASP.NET comes with a great solution to avoid these kinds of problems: the Web.config file, expression syntax, and the WebConfigurationManager class you use to read from Web .config.

The Web.config File

You've used the Web.config file a number of times in this book to store information about connection strings, membership, roles and profile information, and more. You also briefly saw the <appSettings> element that enables you to store data in a key/value pair using <add> elements. The<appSettings> element enables you to store simple information, such as an e-mail address, and retrieve that value by its key. For example, to store an e-mail address, you can add the following to the Web.config file:

  <add key="FromAddress" value="" />

The <appSettings> element is placed outside the <system.web> element in the Web.config file, yet still within the parent <configuration> element.

Obviously, you need a way to access the data in <appSettings> at run time. You can do this in a couple of ways, including expression syntax and the WebConfigurationManager class, both of which are discussed next.

Expression Syntax

Expression syntax enables you to bind control properties to resources, such as those found in the <appSettings> element in Web.config, connection strings, localization resource files, and various routing settings used in URL rewrite scenarios. To display data from the <appSettings> element, you use the following syntax, where AppSettingKeyName refers to a key you define in Web.config:

<%$ AppSettings:AppSettingKeyName %>

For example, to display a copyright notice on your pages in a Literal control, you can add the following setting to Web.config:

<add key="Copyright" value="Copyright by Wrox" />

You can then display this text in a Literal control like this:

<asp:Literal ID="Copyright" runat="server" Text="<%$ AppSettings:Copyright %>" />

To make it even easier to set properties like Text as in the preceding example, Visual Studio comes with the Expression Editor. To access this dialog box, select a control in Design or Markup View, open its Properties Grid, and click the ellipsis for the (Expressions) item, shown in Figure 19.1. You may find that the (Expressions) item does not always show up when in Markup View. If that's the case, switch to Split View or Design View first.

Figure 19.1


The Expressions dialog for the Literal control opens, enabling you to bind control properties to expressions. Visual Studio limits the list of properties of the control to those that can be bound using an expression. To bind the Text property of the Literal control to an application setting, first click Text on the left side of the dialog box, choose AppSettings from the Expression Type drop-down list on the right, and finally, choose the desired AppSetting from the drop-down list in the Expression Properties section. Figure 19.2 shows the complete Expressions dialog box for a Literal control used to display the copyright text.

Figure 19.2


When you click OK, Visual Studio modifies the Text property of the Literal control so it contains a reference to the correct application setting.

Getting values from the Web.config using expression syntax is useful, but may not cover all your needs. Therefore, it's good to know that you can retrieve the values programmatically as well. To do this, you can use the WebConfigurationManager class.

The WebConfigurationManager Class

The WebConfigurationManager class from the System.Web.Configuration namespace provides access to data that is stored in configuration files. It has special support for the appSettings and connectionStrings elements of the Web.config file, enabling you to retrieve data from those sections with a single line of code. The following snippet shows you how to retrieve the FromAddress value you saw earlier from the <appSettings> element:


Imports System.Web.Configuration
Dim fromAddress As String = WebConfigurationManager.AppSettings.Get("FromAddress")


using System.Web.Configuration;
string fromAddress = WebConfigurationManager.AppSettings.Get("FromAddress");

The Get method always returns data as a string, so you'll need to convert it to a proper type if you're expecting anything other than a string. For example, if you have stored a boolean value in Web.config like this:

<add key="SendMailOnError" value="true" />

you need to use the following code to retrieve and convert the value:


Dim sendMail As Boolean = 


bool sendMail = 

Although you can access the WebConfigurationManager class in the Code Behind of your Web Forms and user controls directly (provided you have imported the System.Web.Configuration namespace), I prefer to create static, read-only properties in a custom configuration class that accesses theWeb.config file to get the values. You see how to do this in the following exercise.

Try It Out: Moving Application Settings to Web.config

In this Try It Out, you create a class with a few properties that get their values from the Web.config file. You then use the properties of this class in your code to replace the hard-coded values that were used earlier.

1. Inside the App_Code folder, create a new class file and call it AppConfiguration.vb or AppConfiguration.cs. In C#, remove the constructor code, shown in the following code block:

public AppConfiguration()
  // TODO: Add constructor logic here

Because the class is going to have static properties exclusively, you don't need the constructor.

2. At the top of the class file, add an Imports/using statement for the System.Web.Configuration namespace:


 Imports System.Web.Configuration


 using System.Web.Configuration;

3. Add a new Shared (static in C#), read-only property to this class that returns the FromAddress from the Web.config file. Recall from Chapter 5 that a Shared/static member (like a method or a property) operates on the class itself, and not on an instance of that class.


Public Class AppConfiguration
  Public Shared ReadOnly Property FromAddress() As String
      Dim result As String =
      If Not String.IsNullOrEmpty(result) Then
        Return result
     End If
     Throw New Exception("AppSetting FromAddress not found in web.config file.")
   End Get
  End Property
End Class


public class AppConfiguration
  public static string FromAddress
      string result = WebConfigurationManager.AppSettings.Get("FromAddress");
      if (!string.IsNullOrEmpty(result))
        return result;
      throw new Exception("AppSetting FromAddress not found in web.config file.");

4. Repeat the previous step, but this time create the following three properties by creating a copy of FromAddress:

· FromName

· ToAddress

· ToName

Don't forget to rename all three occurrences of FromAddress to the new property name.

5. Still inside the AppConfiguration class, create a boolean property called SendMailOnError:


Public Shared ReadOnly Property SendMailOnError() As Boolean
    Dim result As String = 
    If Not String.IsNullOrEmpty(result) Then
      Return Convert.ToBoolean(result)
    End If
    Throw New Exception(
                "AppSetting SendMailOnError not found in web.config file.")
  End Get
End Property


public static bool SendMailOnError
    string result = WebConfigurationManager.AppSettings.Get("SendMailOnError");
    if (!string.IsNullOrEmpty(result))
      return Convert.ToBoolean(result);
    throw new Exception(
                "AppSetting SendMailOnError not found in web.config file.");

6. When you're ready with the five properties, save and close the AppConfiguration file.

7. Open the Code Behind of ContactForm.ascx in the Controls folder, locate the code that sets the From and To addresses, and replace the hard-coded values with their AppConfiguration counterparts:


myMessage.From = New MailAddress(AppConfiguration.FromAddress, 
myMessage.To.Add(New MailAddress(AppConfiguration.ToAddress, 


myMessage.From = new MailAddress(AppConfiguration.FromAddress, 
myMessage.To.Add(new MailAddress(AppConfiguration.ToAddress, 

Notice how IntelliSense helps you pick the correct property of your AppConfiguration class.

8. This is also a good moment to delete the line of code that calls the Sleep method (near the end of the SendButton_Click method) that you added there in Chapter 10 to simulate a slow mail server. On your production site, you want this to go as fast as possible.

9. Save your changes and close the file.

10. Open the Global.asax file and wrap the entire code in Application_Error in an If check that ensures that SendMailOnError is set to True. Additionally, change the hard-coded e-mail addresses to use the FromAddress and ToAddress from the AppConfiguration class instead:


Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
  If AppConfiguration.SendMailOnError Then
    If HttpContext.Current.Server.GetLastError() IsNot Nothing Then
      Dim myMessage As MailMessage = New MailMessage(AppConfiguration.FromAddress,
               AppConfiguration.ToAddress, mailSubject, message)
    End If
  End If
End Sub


void Application_Error(object sender, EventArgs e)
  if (AppConfiguration.SendMailOnError)
    if (HttpContext.Current.Server.GetLastError() != null)
      MailMessage myMessage = new MailMessage(AppConfiguration.FromAddress,
                     AppConfiguration.ToAddress, mailSubject, message);

11. Open Web.config and add the following elements to the <appSettings> element. Change the e-mail addresses for FromAddress and ToAddress to your own:

    <add key="FromAddress" value="" />
    <add key="FromName" value="Planet Wrox" />
    <add key="ToAddress" value="" />
    <add key="ToName" value="Planet Wrox" />
    <add key="SendMailOnError" value="true" />

12. Save all your changes and press Ctrl+F5 to open the homepage in your browser. Go to the Contact page and fill in the contact form. You should receive an e-mail at the address you specified in the previous step.

13. Request a nonexistent page in your browser. For example, change the page name in the address in the browser's address bar to DefaultTest.aspx. You should receive a "File Not Found" message and an e-mail with the exception details, just as in the preceding chapter.

14. Go back to Visual Studio, open Web.config, and change the setting for SendMailOnError from true to false:

  <add key="SendMailOnError" value="false" />

15. Save your changes, and again request a page that doesn't exist. Because you changed the SendMailOnError setting, you shouldn't get an e-mail with the exception details.

How It Works

The properties of the AppConfiguration class look in the Web.config file for the requested application settings. When the setting is not defined or does not contain a value, each property throws an exception. This is useful to detect missing application settings at an early stage. Instead of silently returning an empty value, you now get an exception that reminds you to add the required application setting.

At run time, the code accesses these properties like this:


 myMessage.From = New MailAddress(AppConfiguration.FromAddress, 


 myMessage.From = new MailAddress(AppConfiguration.FromAddress, 

Because the properties have been defined as Shared (static in C#), you can access them directly on the AppConfiguration class, without the need to create a new instance of AppConfiguration first.

Although you could access the <appSettings> element in Web.config directly in the code (for example, you could use WebConfigurationManager.AppSettings.Get(”FromAddress”) to get the e-mail address in ContactForm.ascx directly), it's better to wrap the <appSettings> elements in shared properties in their own class. This solution gives you IntelliSense on the AppConfiguration class, making it easy to see what configuration properties are available. It also enables you to write centralized code that throws exceptions when the required application settings cannot be found or that supplies sensible defaults. Notice how the properties throw an exception only when a valid value cannot be returned. If you access Web.config directly in your own code, you would need to check for valid values every time you access a setting.

The same principle is used for the SendMailOnError setting. When an exception occurs at run time, the code in Application_Error now consults the SendMailOnError property. This property in turn checks the <appSettings> element of Web.config to determine if an error message should be e-mailed. Because the SendMailOnError property is a boolean, the code uses Convert.ToBoolean to convert the string returned from the Web.config file into a boolean.

By storing values in Web.config instead of hard-coding them, your site becomes easier to maintain and deploy. When you go live, all you need to do is create a copy of Web.config for your production environment and change a few settings. This enables you to turn off error logging by e-mail on your development machine easily.

With the hard-coded application settings moved to the central Web.config file, the next step in the deployment process is optimizing your external CSS and JavaScript references.

Introducing Bundling and Minification

Bundling and minification are two new features that have been added to ASP.NET 4.5. Both are designed to improve the performance of your site by minimizing the number and size of your client CSS and JavaScript files. With bundling, the ASP.NET run time combines one or more CSS or JavaScript files into a single request. This minimizes the network overhead as the browser needs to make fewer requests. Minification works by removing irrelevant code from these files. Combining these two techniques greatly enhances the performance of your site.

The cool thing about bundling and minification is that they are really simple to do, and require hardly any code. As an example, imagine you have two CSS files in your Styles folder called 1.css and 2.css. Without bundling and minification, you may have something like this in your master page:

<link href="Styles/1.css" rel="stylesheet" type="text/css" />
<link href="Styles/2.css" rel="stylesheet" type="text/css" />

To enable bundling and minification, you change these two lines into the following single line:

<link href="Styles/css" rel="stylesheet" type="text/css" />

Notice that you no longer specify a filename after the folder name. Instead, you just specify a file extension — css in this case. This instructs the ASP.NET run time to take all files with a .css extension from the Styles folder, bundle them into a single response, and minify them by removing unnecessary content like whitespace and comments. This final result is then streamed to the browser, where it's interpreted in exactly the same way as it was with the two separate files.

You can bundle and minimize JavaScript files the same way by specifying js as the file extension rather than css.

One problem with the previous code example is that the browser caches the result for the URL Styles/css. Even if you change the underlying CSS or JavaScript files, the browser may continue to use the old files. You can overcome this problem by using the ResolveBundleUrl method and passing in the path to the CSS or JS files you want to bundle and minify. ResolveBundleUrl then generates a unique key for the files that is appended to the query string. As long as the files are unmodified on disk, ResolveBundleUrl keeps returning the same key, which tells the browser it's safe to keep using a cached copy of the file. However, as soon as you change one of the files, the key changes as well, which in turn causes the browser to request a fresh copy of the bundle from the server. You see how this works in the next exercise.

Enabling bundling and minification in your ASP.NET website is a three-step process:

1. Install the Microsoft.Web.Optimization package using NuGet.

2. Enable bundling by writing some code in Global.asax.

3. Remove existing <link> and <script> elements pointing to CSS and JavaScript files and replace them with a single <link> or <script> element per file type pointing at the correct source folder.

The current Planet Wrox website doesn't benefit a lot from bundling and minification because the number of CSS and JavaScript files is quite low. In addition, the CSS for the site is placed in the Themes folder, which is not supported by the bundling and minification functionality.

However, to show you how to use bundling and minification in your own sites where it may result in improved performance, in the following exercise you optimize a few style sheets you add to the Styles folder so their content is bundled and minified.

Try It Out: Using Bundling and Minification

In this exercise, you add two new CSS files to the Styles folder. You then enable bundling and minification for this folder so you can see how this affects the CSS code that gets sent to the client.

1. Create a new folder called Styles in the root of your site. You may already have this folder from earlier exercises in this book, in which case you can skip this step.

2. Install the Microsoft.Web.Optimization package. To do this, choose Tools Ø Library Package Manager Ø Package Manager Console and run the following command:

Install-Package Microsoft.Web.Optimization

3. Open up your Global.asax file and in the Application_Start event handler that should already be there, add the following code below the line that creates the ScriptResourceDefinition.





4. Add a new CSS file to your Styles folder and call it Test1.css. Remove the existing code and add the following code to underline all headings at level one:

  text-decoration: underline;

5. Add another CSS file to your Styles folder and call it Test2.css. Remove the existing code and add the following code to change the color of all headings at level one to green:

  color: Green;

6. Open the Frontend master page and directly after the opening <body> tag add the following <link> element:

<link href="<%=Microsoft.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl(
         "∼/Styles/css")%>" rel="stylesheet" type="text/css" />

Because of the way ResolveBundleUrl works, you can't use it in the <head> section of the page and you'll get an error if you try.

7. Save all your changes and request the homepage in your browser. Notice how the heading is now underlined and green.

8. Open the HTML source for the page in the browser and locate the <link> element near the opening <body> tag. It should look similar to this:

<link href="/Styles/css?v=-204869685048678205" rel="stylesheet" type="text/css" />

The v parameter ensures that the browser always gets a fresh copy of the page if you make a change to the underlying CSS files. The exact value for the v parameter will be different on your machine.

9. Request the URL set in the href attribute in your browser directly. Your browser's address bar should look similar to this:


The CSS code you see should look similar to this:


10. Go back to VS and delete Test2.css from the Styles folder.

11. Request the homepage in your browser again. The heading should still be underlined, but the green font has now gone.

12. Repeat steps 8 and 9 and notice how both the query string parameter and the CSS have changed to reflect the deleted style sheet.

How It Works

When ASP.NET encounters a request for a folder followed by a file extension (for example, /Styles/css or /Scripts/js), it takes all files with the extension in the folder, combines them into a single file, and then optimizes the code by removing unneeded code such as comments and irrelevant whitespace. The result of this operation is streamed back to the browser as a single file. To overcome caching issues, you don't point to /Styles/css from your server code directly. Instead, you call the ResolveBundleUrl method on the Bundles collection to create a path that contains a cache key. Whenever the underlying files change, the cache key changes as well, which causes the browser to fetch a fresh copy from the server. To enable the bundling and minification in the first place, you call EnableDefaultBundles on the Bundles collection during the website's Start event in Global.asax.

Notice how in the final CSS from step 9 the underline property comes first. The standard logic for the bundling mechanism is to put files in alphabetical order. Some exceptions to this rule exist. For example, known frameworks such as jQuery that other code may depend on are included first to avoid dependency issues.

Bundling and minification are fully extensible, meaning you can fully customize the way the files are included and minified. For more information, check out this blog post:

Now that you have seen how you optimize your site for the way CSS and script references are handled, you're ready to create a copy of the site for deployment.

Copying Your Website

During development of your site, you use IIS Express, which ships with Visual Studio. Although this server is great for local development, it's not designed to be used in a production environment. To put your site in production, you need to deploy it to a machine that runs the full version ofInternet Information Services (IIS), Microsoft's professional web server. In this section you see how to prepare your site so it can be run under IIS. Later in this chapter, you see how to install and configure IIS.

To deploy your website to a production server, the deployment targets shown in the following table are available, right from within VS.

Deployment Option


File System

Enables you to create a copy of the site on the local filesystem of your development machine or a networked machine. This option is useful if you want to move the files manually to your production server later.

Local IIS

Enables you to create a copy of your site that will run under your local IIS installation.

FTP Site

Enables you to send the files that make up your web application directly to a remote server using FTP.

Remote Site

Enables you to send the files that make up your web application to a remote IIS server. For this option to work, the remote server needs to have the Front Page Server Extensions installed. Check out the documentation that comes with IIS or consult the administrator of your remote server for more help with this option.

If you are using a commercial version of Visual Studio, you can access these four deployment targets from the two main ways of deployment that Visual Studio offers: Copy Web Site and Publish Web Site. If you're using the free Express edition, you can use only Copy Web Site. The Copy Web Site option simply creates a copy of the site whereas Publish Web Site also compiles all the code into one or more assemblies (.dll files), making it impossible to change the code on the server. For a description of the differences between the two, check out this MSDN article:


At the very beginning of this book, you learned about the differences between Web Site Projects (WSP) and Web Application Projects (WAP). For this book, I have chosen to use the WSP model because it's easier to work with for beginners and supports a few features not available to WAPs (such as Profile and the dynamic App_Code folder). Unfortunately, there is one major feature that WAP supports and WSP doesn't: Web Packaging. This is a mechanism to create a setup package of your entire website so it can easily be deployed to a production server, taking the differences in configuration between the development and production machines into account. For more information about Web Packaging in WAPs, check out the list of links on deployment at the Visual Studio Team blog via Although the articles target Visual Studio 2010, you'll find that the concepts discussed still apply.

Creating a Simple Copy of Your Website

The Copy Web Site command simply creates a copy of your site using any of the four transportation options. This is a great way to quickly copy your site to another location, including your production server, or even to a portable media device like a USB stick that you can take with you. You can access the Copy Web Site option from the main Website menu or by right-clicking the site in the Solution Explorer.

Before you create a copy, it's a good idea to check the state of your website. You should do a full recompile where Visual Studio compiles all the code and pages in your website. This helps you detect any problems in your website before you deploy it to a production environment.

Deploying a site is also a good moment to do some housekeeping. To avoid slowing down the deployment process and to keep your site as lean and clean as possible, you should delete the files from your website that you don't need in production.

In the next exercise, you see how to use the Copy Web Site command to create a copy of the entire Planet Wrox project. In a later exercise, you use this copy again when you configure IIS for your production website.

Try It Out: Using the Copy Web Site Option

In this Try It Out, you use the Copy Web Site option together with the Local File System option to create a copy of the site. The other three transportation options (FTP, Local IIS, and Remote IIS) work similarly. The biggest difference with these options is that they ask you for details about the destination, such as a username and password, or the IIS website you want to use. With the copy you create in this exercise, you can configure an IIS website manually, something you see how to do later in this chapter.

1. Close all open files in Visual Studio and then choose Build ⇒ Rebuild Web Site from the main menu. Doing so forces Visual Studio to recompile the entire site even if it already had compiled some parts of it. Visual Studio lists any problems your site may have in the Error List. To verify that your site is error free, open the Error List (choose View ⇒ Error List from the main menu) and make sure you don't have any compilation errors. Fix any errors you may have in your site.

2. When the Error List is empty, choose Website ⇒ Copy Web Site or right-click the site in the Solution Explorer and choose Copy Web Site.

3. At the top of the dialog box, click the Connect button to bring up a dialog box that enables you to choose the destination location for your site.

At the left side of the dialog box, make sure that File System is selected. Then on the right side, locate the C:\BegASPNET folder, click it once to select it, and then click the Create New Folder button at the top-right corner of the dialog box. Type Release and press Enter to apply the new name. Figure 19.3 shows the final dialog box.

Figure 19.3


Click Open to choose C:\BegASPNET\Release as the destination location for your copy operation.

4. In the Copy Web Site dialog box, put focus on the list at the left by clicking a file or folder and then press Ctrl+A to select all files in the Source Web Site list.

5. Click the Synchronize Selected Files button (the third button with the two arrows facing in opposite directions) between the two lists, visible in Figure 19.4. This starts the synchronization process. Because the folder displayed on the right side is empty, all files from the left list are copied to the right. When copying is complete, your dialog box should look like Figure 19.4.

Figure 19.4


6. Next, open File Explorer (on Windows 8) or Windows Explorer (on older versions of Windows) and browse to C:\BegASPNET\Release. Verify that all relevant files that make up your site are there.

How It Works

The Copy Web Site option simply creates a copy of all files that make up your site. It can create a copy of the site at different locations, including the local filesystem, an FTP server, and an IIS server. In this exercise, you created a copy at a local hard drive. The first two buttons with arrows between the two file lists in Figure 19.4 enable you to copy files from the source to the remote location or vice versa. The third button, with the two arrows, enables you to synchronize, rather than just copy over the files. When you create a copy on your local system this may not seem like a big deal, but when you're creating the copy over a slow FTP connection, you'll be glad this tool uploads only new and changed files, and leaves unmodified files untouched. If the same file has been changed in both the source site and the remote site and you synchronize these files, the tool prompts you to indicate in which direction you want to copy. Likewise, if you synchronize a file that has been deleted in one site, the tool will prompt you to indicate if you want to delete the file from the other site.

In this exercise, you opted to copy the files to the local filesystem. This is a great way to create a copy that is detached from the development environment that can be run on your local machine. You can, of course, copy the same set of files to another machine using an FTP program, a USB stick, and so on. Also, if you host your site externally, your hosting provider may offer a web-based interface to upload these files to its server.

The detached local copy enables you to make modifications to a few files first (like Web.config) and then upload everything to your host.

Besides copying a website, the commercial versions of Visual Studio also support publishing your website.

Publishing Your Website

The Publish Web Site command, available only in the commercial versions of Visual Studio and not in the Express edition, is similar to the Copy Web Site option in that it creates a copy of the website you can use for deployment. However, it's different in that it enables you to precompile the application, which means all the code in the Code Behind of your ASPX pages, controls, code files in App_Code, and so on are compiled into .NET assemblies; files with a .dll extension, stored in the bin folder of your site. The main benefits of precompiling are source protection (others with access to the server can't look into your source) and an increased performance the very first time a page is requested. Pages that are not precompiled are compiled on the fly when they are requested the first time, which takes a little bit of time. Remember that regular visitors to your site will never be able to see the source of your application. All they'll be able to see is the final HTML that gets sent to the browser.

The Publish Web Site command is available from the Build menu and brings up the dialog box shown in Figure 19.5.

Figure 19.5


Clicking the ellipsis at the end of the Target Location brings up the same dialog box shown in Figure 19.3, enabling you to choose a target location. When you select the Allow This Precompiled Site to Be Updateable option, Visual Studio compiles all your VB.NET and C# code into .NET assemblies and places them in a bin folder at the root of your site. It leaves the markup in ASPX and ASCX files alone. However, with this option turned off, all the markup code is compiled into .dll files as well. The actual files still need to be deployed to the server, but their content has been replaced with placeholder text: “This is a marker file generated by the precompilation tool, and should not be deleted!” When the page is requested by a browser, the ASP.NET run time finds the appropriate content in the assemblies in the bin folder and serves its content as if it were a normal page. This latter option is especially great if you want to prevent other people with access to your server from altering your site after it has been deployed. Because all the source and markup is compiled into .dll files, there is no way to change it on the server anymore, other than uploading a new set of published files.

Copying or publishing your website to a new folder on your local system is only one step of the deployment process. The next part is configuring the web server so it knows where to look for your files.

Running Your Site Under IIS

Up until now, you've been using IIS Express, which ships with Visual Studio, to debug and test your application. However, because requests to this server are limited to those coming from the localhost to minimize security implications, you'll need to use the full IIS, which comes with most major Windows versions. To have your website run under IIS, you need to perform the following steps:

1. Install and configure IIS.

2. Install and configure the .NET Framework 4.5.

3. Configure security settings.

Depending on the current state of your system, some of these actions are optional. In the following sections, you see how to carry out these steps.


Installing and configuring a web server can be a complex task. You have many factors to take into account, including your operating system, its configuration, the account you use to log on to your machine, the final SQL Server you're going to use, and more. Don't panic if you get stuck. Instead, visit the IIS website at for detailed walkthroughs, or come over to this book's own discussion forum at where you'll find fellow programmers (including me) that will help you succeed.

The steps described in the remainder of this chapter should work on Windows 7, Windows 8, Windows Server 2008 R2, and Windows Server 2012. For a lot more information about IIS, including help with installing IIS on older versions of Windows not discussed here, check out the official IIS website at

Installing and Configuring the Web Server

Although IIS ships with most Windows versions, it's not installed by default, so you need to do that first. You also need to make sure that your version of Windows supports IIS. Although the Starter and Home Basic versions of Windows 7 and 8 ship with some parts of IIS, you can't run ASP.NET pages on them, so you need at least the Home Premium edition. On the server-based versions of Windows, IIS is fully supported. If you're hosting your site with an external hosting company, you can skip the following sections on installing IIS.


Even though IIS is supported on consumer versions of Windows such as Windows 7 and 8, it doesn't mean these operating systems are the best choices for hosting your website. You typically use these versions of Windows for local development and testing, whereas the server versions of Windows (such as Windows Server 2008 R2 and Windows Server 2012) are used for hosting production websites.

To install and configure IIS on your Windows machine, you need to be logged on as an Administrator. If the account you use to log on to your machine does not have administrative privileges, you need to ask your administrator to install and configure IIS for you.

In addition to installing IIS, you also see how to create and configure the website in IIS. Because of the way security works under Windows, your site probably won't work immediately after you configure IIS unless you change some of the security settings under Windows. You see how to do this in the section “Understanding Security in IIS” and the Try It Out entitled “Configuring the Filesystem.”

You'll be able to test out your IIS settings more easily if you already have SQL Server 2012 Express installed. This is the case if you followed along with the exercises in Chapter 12. If you haven't installed SQL Server 2012 Express yet, refer to the section “Installing SQL Server 2012 Express” in Chapter 12 for installation instructions. If you have one of the commercial versions of SQL Server, or have SQL Server on a remote machine, pay special attention to the section “Moving Data to a Remote Server” in this chapter and to Appendix B.

Making Sure IIS Is Installed

The easiest way to install IIS is through the Web Platform Installer (WPI). WPI is installed with Visual Studio so if you're carrying out these steps on your development machine, you already have the WPI. If you're following these steps on another machine (running Windows Server for example), you need to download and install WPI first. You can download WPI from and install it by clicking the Install Now button. If this link has changed by the time you read this document, go to instead, or search the web for “Web Platform Installer download” to find one of the other Microsoft locations that lets you download and install WPI.

Once WPI is installed, it starts automatically, or you can run it from the Windows Start menu or Start screen. When it's done loading, switch to the Products tab, at the top of the screen enter IIS recommended, and press Enter. WPI should list the IIS Recommended Configuration, as shown inFigure 19.6.

Figure 19.6


Click Add to add this item to the list of items to be installed. If the Add button is disabled, parts of IIS are already installed.

Next, use the search box again and search for IIS: ASP.NET. Depending on your version of Windows, this should bring up an item called IIS: ASP.NET or IIS: ASP.NET 4.5 (as well as other, unrelated items). The IIS: ASP.NET or IIS: ASP.NET 4.5 item is needed to run ASP.NET under IIS, and is a critical component to run your site successfully. Select this item and click Add. If you see both items choose IIS: ASP.NET 4.5. Finally, click the Install button at the bottom of the screen and then accept the license terms. After a while, you should get a confirmation that IIS and its components were installed successfully.

For detailed instructions on manually setting up IIS, check out these articles on the official IIS website:

When IIS is installed successfully, you need to make sure you have the Microsoft .NET Framework version 4.5 installed.

Installing and Configuring ASP.NET

If you installed Visual Studio 2012 (any edition) on your target machine or you're running Windows 8 or Windows Server 2012, you already have the .NET Framework 4.5 installed. Otherwise, you need to download it. You can use the Web Platform Installer as discussed earlier, or you can download the redistributable package from the Microsoft site at Follow the Download or Install link or use the search option and search for “download .NET Framework 4.5.” Make sure you download the full version of the .NET 4.5 Framework and not an earlier version or the Client Profile package. After you have downloaded the .NET Framework, run the installer and follow the on-screen instructions.

If you already had the .NET Framework 4.5 on your machine and installed IIS afterward, you need to tell IIS about the existence of the framework. Normally, this is done during installation of the .NET Framework, but if you installed IIS later, you need to do this manually. You only need to do this on Windows 7 and Server 2008 R2. For Windows 8 and Server 2012, ASP.NET 4.5 is registered correctly when you install IIS through the WPI. To register ASP.NET in IIS, follow these steps:

1. Open a command prompt in Administrative mode. To do this, click the Start button, type cmd in the search box, and press Ctrl+Shift+Enter to start the command prompt with elevated permissions. When you confirm the action, the command prompt will open with elevated permissions.

2. Navigate to the .NET Framework version 4 folder by entering the following command and pressing Enter:

cd \Windows\Microsoft.NET\Framework\v4.0.30319

3. Because .NET 4.5 is an in-place replacement for .NET 4, this folder uses the 4.0 version number. Note that the actual version number following v4.0 may be slightly different on your machine if newer versions of the .NET Framework have been released by the time you read this book. Also, if you are using a 64-bit version of Windows, you should use the Framework64 folder. Use Windows Explorer to find out the correct folder before you enter it at the command prompt.

4. Type aspnet_regiis -i and press Enter again.

5. After a while, you should get a message that ASP.NET 4.5 was registered with IIS successfully.

Now that IIS and the .NET Framework have been installed and configured correctly, the next step is to configure your website under IIS. You see how to do this in the next Try It Out exercise. After the Try It Out, you learn more about configuring security permissions for your system.

Try It Out: Configuring Your Site

In this exercise, you see how to configure the standard “Default Web Site” that ships with IIS. Although it's possible to create more than one site under IIS on Windows 7, Windows 8, Windows Server 2008 R2, and Windows Server 2012, this option is not discussed here. Contact your system administrator or read the documentation that comes with IIS to learn more about creating multiple websites under IIS. Most of the steps in Windows 8 are identical to those in Windows 7, Windows Server 2008 R2, and Windows Server 2012. However, the screens you see in the following exercise are taken in Windows 8 and are slightly different on the other operating systems.

If you're doing this exercise on a machine other than the one you used to build the Planet Wrox site, be sure to copy the BegASPNET folder to the root of the C drive of the target machine. Also make sure this machine has access to SQL Server 2012, installed either locally or on another remote machine.

1. Open the Internet Information Services (IIS) Manager. You find this item in the Administrative Tools section of the Control Panel, which you can access through its System and Security category. Alternatively, click the Start button or Start screen, type inetmgr, and press Enter. If you get a question about learning more about WPI, click No (you could click Yes if you wanted to; if you do, you're taken to the main WPI section of the Microsoft website).

2. Expand the tree on the left until you see Application Pools and the Default Web Site, as shown in Figure 19.7.

Figure 19.7


3. Click the Application Pools item and confirm you have an entry called .NET v4.5 that uses v4.0 as the .NET Framework version and that has its Managed Pipeline Mode set to Integrated. If you don't have this item, click Add Application Pool in the Actions panel on the right and create a new application pool called .NET v4.5 using the .NET Framework v4.0.30319 with Integrated as the Managed Pipeline mode.


Although the website you built runs on .NET 4.5, you still need to choose .NET v4.0 as the Framework version for the application pool. The reason for this is that ASP.NET 4.5 uses the .NET 4.0 run time which is what you're configuring here.

4. Select the.NET v4.5 application pool (whether it was already there or not) and click Advanced Settings in the Actions panel on the right. Locate the property called Identity and ensure that it is set to ApplicationPoolIdentity. If it's not, click the button with the ellipsis choose the correct item from the Built-in Account drop-down list and click OK. You use this identity later when configuring security. In the same dialog box, make sure the Load User Profile option is set to True. Your final screen should look like Figure 19.8.

Figure 19.8


Click OK to close the Advanced Settings dialog box.

5. Click the Default Web Site item to select it and click Advanced Settings in the Actions panel on the right of Figure 19.7.

6. In the Advanced Settings dialog box, click the Physical Path property, click the ellipsis to open up a folder browser, select the folder C:\BegASPNET\Release, and click OK to confirm the path.

7. In the same dialog box, click Application Pool, then click the ellipsis, choose the application pool from step 3 labeled .NET v4.5, and click OK. Your Advanced Settings dialog now looks like Figure 19.9.

Figure 19.9


Click OK again to close the Advanced Settings dialog box.

8. Next you need to make sure that IIS is configured to use a sensible default document; the document that is served when you request a folder name or the root of the site. The Planet Wrox site uses Default.aspx, which is the most common default document name for ASP.NET websites. To check this, make sure Default Web Site is the selected option in the tree on the left. Then double-click the Default Document option in the IIS Features list (below the items you see in Figure 19.7). Make sure that Default.aspx is present and at the beginning of the list. If the item is not there, add it manually. To do this, click the Add link in the Actions panel to add it. Then use the Move Up links to move it to the top of the list. Click Yes when you see the warning about inheriting changes. Your dialog box should look similar to Figure 19.10.

Figure 19.10


9. You can now close the Internet Information Services Manager, because the site is configured correctly as far as IIS is concerned. However, it still won't run correctly because you need to configure security permissions on the filesystem, as you see later.

How It Works

Each new IIS installation has a Default Web Site, the site that listens to http://localhost by default. In this exercise, you configured this default website to run Planet Wrox, but you can also create a whole new site that can run side by side with other websites. You pointed the root of the site to the Release folder that contains your website. With that mapping set up, IIS is able to see what files to serve when you request a URL like http://localhost. It means that a URL like http://localhost/Login.aspx is mapped to the physical file at C:\BegASPNET\Release\Login.aspx. You also assigned the website an application pool — an IIS mechanism to isolate and configure one or more IIS websites in one fell swoop. Two websites running in different application pools do not affect each other in case of a problem such as a crash. In this exercise you selected an application pool that uses the .NET 4.5 Framework and that uses the Integrated Pipeline mode. In this mode, IIS and ASP.NET are tightly integrated, which means you can use ASP.NET features (such as Forms Authentication, which you saw in Chapter 16) in standard IIS functionality such as serving static files. For more information about this mode, check out the official IIS website via

At the end of the exercise, you configured a default document, the file that is served when you request a URL without an explicit filename, like http://localhost/ or http://localhost/Reviews/. When you configure Default.aspx as the default document, IIS tries to find and serve a file by that name.

The final thing you need to do to make sure your site runs on your local IIS installation is configure the security settings. This is discussed in the following two sections.

Understanding Security in IIS

Because of the seamless integration with IIS Express, you may not realize what happens under the hood, and what security settings are in effect when you browse pages in your site. To use resources in your site, such as ASPX files, Code Behind files, the database in the App_Data folder, and the images in your site, your web server needs permissions from Windows to access those resources. This means that you need to configure Windows and grant access to those resources to the account that the web server uses. But what exactly is that account? The specific account that needs permission depends on a number of factors, including the version of Windows, whether you run your site under IIS or IIS Express, and on a number of settings within IIS.

In most cases, however, you have only two scenarios to consider: using IIS Express or the full version of IIS as your web server.

In the former case, the account that IIS Express uses is the account you use to log on to your Windows machine. This account is usually something like DomainName\UserName or MachineName\UserName. While logged in with this account on Windows, you start up Visual Studio, which in turn starts up IIS Express. This means that the entire web server runs with your credentials. Because it's likely that you're an Administrator or a power user on your local Windows machine and have permissions to access all files that make up your site, things probably worked fine so far without any changes to the security settings.

In the latter case, where IIS is used, things are quite different. By default, an ASP.NET application under IIS runs with a special account created when you installed IIS. This account is called ApplicationPoolIdentity.

You won't find the ApplicationPoolIdentity user account on your system directly, because it depends on the name of the configured application pool.

Because the application pool you saw earlier runs in Integrated Pipeline mode, you only need to configure a single user account. If you are running in Classic mode (which isn't necessary for the Planet Wrox website) you also need to configure another account called IUSR. This account is used by IIS to serve non-ASP.NET content such as HTML files and images. Consult the IIS documentation for more information about Classic mode and the IUSR account.

After you have determined the account that you need to configure, the final step is to configure the filesystem.

NTFS Settings for Planet Wrox

Regardless of the account you are using, you need to make changes to the Windows filesystem so the web server is allowed to access your resources.

Folder Name



Release (located at C:\BegASPNET\)

List folder contentsRead

The web server account needs to be able to read all the files and folders that make up the website. Child folders, like Reviews, need to be set up to inherit these settings.

App_DataGigPics(both located under C:\BegASPNET\Release)


The web server account needs to be able to read from and write to the Microsoft SQL Server databases in the App_Data folder. It also needs to be able to save the uploaded images in the GigPics folder.



If you're dropping your e-mails locally, you need to configure the TempMail folder as well.

If you came here from Chapter 12 to learn how to configure NTFS for the App_Data folder, you can ignore the Release folder that was created earlier in this chapter. Instead, grant Modify permissions for your own account to the App_Data folder of your site at C:\BegASPNET\Site as per the instructions in the next exercise. You may need to do the same for the GigPics folder, which you could create now at the root of your site, or return to this section after you created the folder in Chapter 14.

In the following exercise, you learn how to configure the security settings for these folders.

Try It Out: Configuring the Filesystem

In this Try It Out, you see how to configure the filesystem for the Planet Wrox website. The exercise shows you screenshots from Windows 8, but the other flavors of Windows have similar screens. Search Windows help for “security NTFS” or contact your administrator if you're having problems carrying out the following steps.

1. Start by opening a File Explorer (called Windows Explorer on versions of Windows before Windows 8 and Server 2012) and then locate your C drive.

2. Browse to C:\BegASPNET, visible in Figure 19.11.

Figure 19.11


3. Right-click the Release folder, choose Properties, and switch to the Security tab (see Figure 19.12). If you don't see the Security tab, your disk is probably not formatted using NTFS and you can skip this exercise.

4. The next step is to add the web server account. Click the Edit button visible in Figure 19.12, and then click the Add button. Type IIS AppPool\ followed by the name of the application pool. If you followed along with the previous exercises, the application pool is called .NET v4.5 which means the account name is IIS AppPool\.NET v4.5. Click OK to add the account.

Figure 19.12


With the account selected in the Group or User Names list, ensure that only List Folder Contents and Read are selected. Your dialog box should end up similar to Figure 19.13.

Figure 19.13


5. Close the dialog box so you return to the Release Properties dialog box shown in Figure 19.12.

6. Click the Advanced button to open the Advanced Security Settings dialog box again. For Windows 7 and Server 2008 R2, click the Change Permissions button and check the Replace All Child Object Permissions check box. For Windows 8 and Server 2012, you find this check box on the Advanced Security Settings dialog box directly. This forces Windows to apply the same security settings to all sub files and folders, replacing all existing settings. Click OK and then confirm the changes that will be made. Finally, close all remaining open dialog boxes.

7. Back in File Explorer / Windows Explorer, right-click App_Data from the Release folder, open its Properties dialog box and then its Security tab, and edit the permissions for the web server account you added in step 4 by adding Modify permissions (this in turn causes some of the other permissions to be selected as well). You need to click the Edit button first to bring the Properties dialog box in editable mode. Figure 19.14 shows the completed dialog.

Figure 19.14


Click OK to close the dialog box.

8. Repeat this step for the GigPics folder and optionally for the TempMail folder.

9. If you are using IIS on a machine that has SQL Server Express, the final thing you need to do is modify your connection strings. If you don't have SQL Server Express installed, refer to the start of Chapter 12 that shows you how to install SQL Server Express Edition as well as SQL Server Management Studio Express Edition. If you're using a different database server, or if you only have SQL Server Local DB Edition installed and don't want to install SQL Server Express, look at the section “Moving Data to a Remote Server” later in this chapter and look at Appendix B, which explains how to configure a different SQL Server.

To modify the connection string, open up Web.config and replace both occurrences of (LocalDB)\v11.0 in the connection strings with .\SqlExpress. This targets a named instance of SQL Server called SqlExpress on the local machine (identified by the dot (.)). In addition, add User Instance=True to both connection strings to run SQL Server under the same user account as the website. Your connection strings should end up like this:

    <add name="PlanetWroxConnectionString1" connectionString="Data 
      Integrated Security=True;User Instance=True"
               providerName="System.Data.SqlClient" />
    <add name="PlanetWroxEntities" connectionString="metadata=
      provider connection string="data source=.\SqlExpress;
         integrated security=True;User Instance=True;
      providerName="System.Data.EntityClient" />

10. To check if the site works, open a browser and go to http://localhost. You should see the Planet Wrox website appear. To verify that everything is in order, browse through the site by requesting pages from the main menu, filling in the contact form, creating a new album, uploading pictures, and so on. If you get an error, refer to the section “Troubleshooting Web Server Errors.”


If you still can't make it work, try configuring the filesystem for the Everyone group. Although, from a security point of view, this is absolutely not the recommended group to use in a production environment, it may help you in finding out whether it's a security issue. If it works for the Everyone account, it's indeed security-related, so you need to make sure you configured the correct accounts. Don't forget to remove the Everyone account later again. If you keep having problems, refer to the next section where you find a number of problems you may run into while deploying as well as a solution.

How It Works

On a standard Windows system, all files and folders are protected using Windows NTFS. To ensure proper operation of your website, you need to grant the account used by the web server the necessary permissions to the files and folders of your website. For most files and folders, Read permission is enough. However, for a few folders you need to change the permissions. Both App_Data and GigPics are written to at run time so you need to grant Modify permissions to these folders. In addition, you need to configure C:\TempMail if your site drops e-mails there locally.

In order for your site to connect to a database, you changed both connection strings in Web.config to target an instance of SQL Server called SqlExpress. The Local DB Edition you used before is great for local development, but not for running your production sites. Instead, you can use SQL Server Express Edition or one of the commercial versions of SQL Server. Appendix B digs much deeper into configuring your site to work with versions of SQL Server other than Express.

Troubleshooting Web Server Errors

When you try to access your site in a web browser, you may run into a number of problems. The first thing you need to do to get helpful error messages is to change the <customErrors> section in Web.config from On to Off or RemoteOnly. This makes it easier to see what's going on. Additionally, you may want to check out the Windows Event Viewer (type eventvwr from the Start menu or Start screen) for more details about errors and hints how to solve them.

This section lists the most common problems and provides a fix for them. You should realize a large number of possible reasons exist for the errors you may get, so it's impossible to cover them all here. If you run into a problem you can't solve, turn to this book's forum at the Wrox community site at You'll find many helping hands (including mine) that understand your problem and can help you find a solution for it.

· It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level — You get this error when your website is not at the root of the web server, or you haven't configured the folder as a separate application. Given the current configuration for the Planet Wrox site, you get this error when, for example, you map your site in IIS to C:\BegASPNET and then browse to http://localhost/Release. To fix this error, make sure that the root of your IIS website points to the folder that contains your main Web .config file; C:\BegASPNET\Release, in this case. You get the same error when you open an incorrect folder in VS; for example, when you open C:\BegASPNET and then browse to http://localhost:12345/Site. Instead, open C:\BegASPNET\Site as the website in VS. You may also run into this error if a subfolder in your site contains aWeb.config file that tries to override settings that are meant to be defined at the root of the site only; for example, if you have a <membership /> element in the Web.config file of the Management folder.

· HTTP Error 401.3–Unauthorized — You get this error when the account used by the web server does not have permission to read the files on disk. To fix this problem, refer to the Try It Out entitled “Configuring the Filesystem” earlier in this chapter and configure the correct permissions.

· Failed to update database “C:\BEGASPNET\RELEASE\APP_DATA\ASPNETDB.MDF” because the database is read-only — You get this error when either the database files have been marked as read-only, or if the account used by the web server is not allowed to write to the database files. In the former case, open the file's Properties in File Explorer / Windows Explorer and verify that the Read Only check box is cleared. In the latter case, ensure that the account used by ASP.NET has at least Modify permissions on the App_Data folder.

· HTTP Error 403.14–Forbidden — Although this error seems to suggest a problem with NTFS permissions at first, it's often caused by an incorrect or missing default document. If you get this error, ensure that the site or folder you are accessing contains a document called Default.aspx and that you configured that document name as a default document in IIS.

· HTTP Error 404.0–Not Found — You get this error when you try to request a file or folder that doesn't exist, such as http://localhost/DoesNotExist or http://localhost/DoesNotExist.gif.

· An error has occurred while establishing a connection to the server. When connecting to SQL Server 2008, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40–Could not open a connection to SQL Server). Alternatively, you may get the error: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified) — You can get these errors for a number of reasons. Although the error message here mentions SQL Server 2008 explicitly, you can also get this error for other versions of SQL Server. Usually, this error is caused by problems reaching the configured database server. You can get it when you misspelled the server's name in a connection string, the server is down, or the server can only be reached from the local machine and is not accessible over the network. To make sure that SQL Server is running correctly, open the Services section of the Administrative Tools (that you find in the Control Panel). Then look under SQL Server and verify that SQL Server is started. Appendix B explains SQL Server security in more detail and provides solutions to these problems.

· Failed to generate a user instance of SQL Server due to failure in retrieving the user's local application data path. Please make sure the user has a local user profile on the computer. The connection will be closed — You can get this error when you forgot to enable the “Load User Profile” option discussed in the Try It Out titled “Configuring your Site.”

· HTTP Error 500.21 - Internal Server Error Handler “PageHandlerFactory-Integrated” has a bad module “ManagedPipelineHandler” in its module list Detailed Error Information — You get this error when ASP.NET is not registered with IIS. Refer to the section labeled “Installing and Configuring ASP.NET” to learn how to fix this issue.

· Runtime Error Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed. Details: To enable the details of this specific error message to be viewable on the local server machine, please create a <customErrors> tag within a “web.config” configuration file located in the root directory of the current web application. This <customErrors> tag should then have its “mode” attribute set to “RemoteOnly”. To enable the details to be viewable on remote machines, please set “mode” to “Off” — You may get this error when a runtime error occurs and the Web.config does not contain a <customErrors> element. However, you may also get the same error when the Web.config file itself contains an error; for example, when you forgot to close an element. To fix this latter category of errors, open the file in Visual Studio and it provides you with more details about the error.

When you are deploying to a machine that also has SQL Server Express edition installed, you are done with the deployment process now. However, if you're dealing with a different SQL Server, the only thing that's left to do is to make sure your new site has the required data. You see how to do this next.

Moving Data to a Remote Server

Releasing a site to IIS on your local machine is pretty straightforward. You simply copy the data to a new location, configure IIS, change a few security settings, and that's it. Because the site continues to use your local copy of SQL Server, it will run fine.

However, in the real world when you need to move your site to an external server or host, things are not so easy. Although copying the files that make up your site is usually extremely simple using an FTP program, copying data from your SQL Server database to your host is quite often a bit trickier. This is because most web hosts don't support the free Express or LocalDB editions, so you can't just simply copy the .mdf files to the App_Data folder at your remote host. Instead, these hosts often offer the full versions of SQL Server, which you can access either with a web-based management tool or with tools such as SQL Server Management Studio.

Getting your database data from your local machine to your remote host is typically a two-step process:

1. Create a .sql script from your local SQL Server database.

2. Send this script to your host and execute it there.

In the next section, you see how to export your database to a .sql file. I won't show you how to run that file at your host to re-create the database because this is different from host to host. Instead, I will give you some general pointers so you know what to look for with your host.

Exporting Your Data to a File

To make it easy to transfer data from your local SQL Server database into a SQL Server database of your web host, SQL Server Management Studio comes with a tool to export your database structure and data to a file. This file then contains all the information required to re-create your database and its data at a remote server.

In the following exercise, you see how to use SSMS to export your database to a file.

Try It Out: Exporting the Planet Wrox Database

This exercise assumes you've already downloaded and installed SQL Server Management Studio Express Edition. If you haven't already done this, refer to the start of Chapter 12 for more details.

1. Start SQL Server Management Studio from the Start menu or Start screen. You should see a screen similar to Figure 19.15.

Figure 19.15


2. Enter (localdb)\v11.0 as the server name and click Login. Your PlanetWrox database should already be listed, but if it's not, right-click the Databases node, click Attach, and then browse for the PlanetWrox.mdf file in your C:\BegASPNET\Site\App_Data folder.

3. Right-click the PlanetWrox database and choose Tasks ⊆ Generate Scripts. If you get a welcome screen, click Next. Ensure that Script Entire Database and All Database Objects is selected, and then click Next. The dialog box shown in Figure 19.16 appears.

4. In this screen, you can choose between two Output Type options. The first enables you to create a text file with the necessary SQL statements, and the second option enables you to talk to your shared hosting provider over the Internet directly. If your host supports this, it can give you the necessary information to configure a provider here. For now, choose Save Scripts to a Specific Location. Then click the Advanced button and change the setting for Types of Data to Script to Schema and Data. The default value of Schema Only would only script your database structure, but not the actual records your tables contain. Set Script Use Database to False. With this setting set to True, code will be included to create a database at the App_Data folder, which likely won't work on a machine other than your own. Click OK to close the Advanced Scripting Options dialog box.

Figure 19.16


5. Click Next twice and the wizard generates the SQL script for you in your Documents folder (as specified in the File Name box shown in Figure 19.16). Open the file in Notepad and look at the SQL statements it contains. Although most of it probably looks like gibberish to you, it can be used as is to re-create the database structure and data on a compatible SQL Server database.

How It Works

The contents of a database can be separated in two categories: the structure of the database and the actual data. When the scripting tool runs, it investigates the structure of your database first and creates SQL CREATE statements for all the items it finds in your database, such as the tables you created in earlier chapters. It then creates INSERT statements that re-create all records such as Reviews, Genres, and even users in the target database. By clearing the Script All Objects check box at the beginning of the wizard, you can selectively choose parts of your database, enabling you to script only a few tables, for example.

At the end, the scripting tool assembles all the SQL statements and saves them to a single .sql file. This file is now ready to be run at your host to re-create the database.

Re-Creating the Database

Although every host has its own rules and procedures when it comes to providing access to their SQL Server, they can be grouped in three categories.


For detailed information about hosting your site with an external hosting party, check out the tutorials in the hosting section of the official ASP.NET site at

First, some hosts don't give you remote access to their database and require you to submit a .sql file so they can execute it for you. In this case, you don't have to do anything other than send the file and wait for the host to create your database.

The second category contains the hosts that allow you to execute SQL statements through a web interface. You typically log in to your online control panel and then execute the SQL statements created by the scripting tool, either by uploading the file or by pasting its contents in a text area in a web page. Regardless of the method, you then end up with a database that you can access from your application. How this works exactly is different with each host, so consult the hosting service's help or support system for more information. Some known issues exist with web-based database management tools from some providers, resulting in errors when you try to run the generated SQL file. Although the file itself is technically valid, the tool may still run into issues with it. If that's the case, contact your host for help on resolving the issue. If you run into issues, one of the things you may want to try is to save your SQL file in a different format. The default format is Unicode, which not all providers understand. To change the format, choose ANSI Text for the Save As option when exporting your data, as shown in Figure 19.16.

The final category contains hosts that allow you to connect to their SQL Server over the Internet. This enables you to use tools like SQL Server Management Studio to connect to the database at your host right from your desktop and execute the SQL scripts remotely. Refer to the first exercise in the section “Using SQL to Work with Database Data” of Chapter 12 to learn more about executing SQL files against a database using SSMS.

After your database is re-created at your target server, you need to reconfigure your ASP.NET application to use the new database by changing the connection strings in your website. For this to work, you need to modify two connection strings: the PlanetWroxConnectionString1 and thePlanetWroxEntities you created in an earlier chapter. How your connection string must look depends on the database you are using and its configuration. Your hosting company or database administrator typically provides this information. For many examples of proper connection strings, check out The following snippet provides a simple example that reconfigures your application to use a database server called DatabaseServer. This example shows a connection string for a SQL Server that requires you to log in with a username and password (in your configuration file, each connection string should be on a single line):

  <add name="PlanetWroxConnectionString1" connectionString="Data 
      Source=DatabaseServer;Initial Catalog=PlanetWrox;User Id=YourUserName;
      Password=YourPassword;" providerName="System.Data.SqlClient"/>
  <add name="PlanetWroxEntities" connectionString="metadata=res://*
      provider connection string="Data Source=DatabaseServer;
        Initial Catalog=PlanetWrox;User Id=YourUserName;Password=YourPassword;

This points both connection strings for the PlanetWrox database to a different SQL Server. Consult Appendix B for more information about configuring your ASP.NET application and SQL Server to operate with each other.

At this stage, you're pretty much done configuring your newly created website. Congratulations! However, before you relax and start enjoying your new website, read the following checklist that helps you secure your site and improve its performance.

The Deployment Checklist

Instead of ending this chapter with general tips about deployment, this section gives you a practical list of things to check when you're ready to put your website in production:

· Make sure you don't have debugging enabled in the Web.config file. This causes unnecessary overhead and decreases performance of your website, because code executes slower and important files cannot be cached by the browser. To ensure debugging is disabled, open the Web.config file you are using for your production environment, and verify that debug is set to false:

<compilation debug="false">

· Make sure you have turned on custom errors by setting the mode attribute of the customErrors element in Web.config to either On or RemoteOnly. In the first case, everyone sees your custom error pages, and in the second case, only users local to the web server can see the error details. Never leave the mode set to Off, because doing so can lead to information disclosure. The following snippet shows a safe configuration of the customErrors element:

<customErrors mode="On" defaultRedirect="∼/Errors/OtherErrors.aspx">
  Optional <error /> elements go here

· Disable tracing, or at least limit the trace information to users coming from the local machine. The following <trace /> element from Web.config blocks tracing for users coming from machines other than the web server itself. Additionally, it stops the trace information from appearing in the page:

<trace mostRecent="true" enabled="true" requestLimit="1000" 
          pageOutput="false" localOnly="true"/>

· Consider setting the retail attribute of the deployment element in machine.config to true:

    <deployment retail="true"/>

This section is used to indicate that the server hosts production-ready versions of your sites, and for all sites on the server, changes all three previous items to a secure setting: debugging and tracing are disabled, and error messages are accessible only to local users.

To make this change, you need to be logged in as an Administrator on your system. Also, be sure to make a backup copy of the file first. Because it serves as the root configuration file for all your ASP.NET websites, you don't want to mess up this file.

· Scan your site for important files that may contain sensitive information (like Word or text documents) and either exclude them from the release version or consider moving them to the App_Data folder. Files in that folder cannot be accessed directly. However, your own code can still access the files as you saw in Chapter 9.

· Make sure you turn on error logging. With the error logging code you created in the previous chapter, you are notified whenever an error occurs, enabling you to proactively keep an eye on your server, fixing errors before they get a chance to happen again.

· If you are using themes in your site, make sure you remove the styleSheetTheme attribute from the <pages> element in Web.config. The Planet Wrox website uses themes, but you added the styleSheetTheme attribute to enable design-time support in Visual Studio. On your production server, all you need is this:

<pages theme="Monochrome">

This way, the page won't include the same style sheet twice.

What's Next

Now that you have finished your first ASP.NET website, I am sure you are looking forward to creating your next site. The Planet Wrox site can serve as a basis for new sites you will build. You probably won't use any of its pages in your site directly, but hopefully this book and the Planet Wrox website inspired you enough to build a new website on your own.

Because this book is aimed at beginners, I haven't been able to provide you with a lot of in-depth information on some important topics. Most subjects that have their own chapter in this book easily warrant an entire book on their own. For example, topics like CSS, AJAX, and LINQ are so extensive that Wrox has published many books about them. Now that you've mastered the basics of these technologies, you can dig deeper into them using the following books in the Wrox Professional series:

· Professional CSS: Cascading Style Sheets for Web Design, 3rd Edition (ISBN: 978-0-470-89152-0)

· Professional ASP.NET 2.0 Design: CSS, Themes, and Master Pages (ISBN: 978-0-470-12448-2)

· Professional ASP.NET 4.5 in C# and VB (ISBN: 978-1-118-31182-0)

· Professional LINQ (ISBN: 978-0-470-04181-9)

· Professional Microsoft IIS 8 (ISBN: 978-1-118-38804-4)

Of course, the web is also a good place for more information. The following URLs may be helpful in your search for more information about ASP.NET and its related technologies:

· — The public discussion forum from Wrox where you can go for all your programming-related questions. This book has its own category on that site, enabling you to ask targeted questions. I am a frequent visitor to these forums and I'll do my best to answer each question you may have about this book.

· — My own website where I keep you up to date about various web programming–related topics.

· — The Microsoft community site for ASP.NET technology. Go here for news on ASP.NET, additional downloads, and tutorials.

· — The official home for ASP.NET at the Microsoft developers website that gives you a wealth of information on ASP.NET.


Obviously, deployment is an important action at the end of the development cycle of your new website. However, it's unlikely that you deploy your site only once. As soon as you release the first version of your site, you'll think of other new and cool features you want to add, making the development of your site a continuous process. To accommodate for this, you need to make your site easy to deploy.

One way to do this is by moving hard-coded configuration settings to the Web.config file, giving you a single location to change parameters for the site in your development and production environments.

When you're ready to roll out your site, it's a good idea to create a copy of your site and clean that up before you send the files to your target server. Copying and then publishing a site is a breeze with the Copy Web Site and Publish Web Site commands.

Because you will deploy your site against IIS, you need to understand some important settings of this web server. In this chapter, you saw how to configure the Default Web Site and make some configuration changes. Because of the way security works in Windows and IIS, you also need to configure your hard drive so that the accounts used by the web server can read the files in your site, and write to specific folders such as App_Data and GigPics.


This chapter has no exercises, because the Planet Wrox site is now completely finished. However, your biggest challenge starts now: building websites with the knowledge you gained from this book. If you ever build a site with the information from this book and want to share it with me, please contact me through my website at Have fun!

What You Learned in this Chapter

.NET assembly

A file with a .dll extension that contains executable and callable .NET code

Application pool

A mechanism to isolate (one or more) websites in IIS to give them their own set of resources


The process of releasing a website from your development environment to the production environment

Expression syntax

A technique that enables you to bind control properties to different resources, such as application settings defined in Web.config


Internet Information Services — Microsoft's web server for the Windows platform

Integrated Pipeline mode

With Integrated Pipeline mode turned on for an application pool in IIS, ASP.NET and IIS are tightly integrated together, enabling you to use ASP.NET techniques for non-.NET resources such as static files


The process of compiling a web application into a set of .dll files, which can be deployed to a production server; without precompilation, the ASP.NET files are compiled on the fly the first time they are requested

WebConfigurationManager class

A .NET Framework class that provides access to data that is stored in configuration files