Programmatically Managing Application Services in ASP.NET

Since version 2.0, ASP.NET ships with a set of the so called Application Services, including Membership, the Role Manager, Personalization, Profile and the SqlWebEventProvider. To enable these features, you have a few options. The most common way is to just start using one of the features, such as Login control on an ASPX page. The default setup is configured to automatically create a SQL Server database in the App_Data folder of a site with the services already enabled. Another very common way, to get more control over the setup is to use the aspnet_regsql tool. This GUI or command line tool gives you more control over the SQL Server and database you're targeting and the exact features you want to install. The downside of this tool is that you need to run it locally and need the permissions to execute it.

I recently discovered that you can also manage the application services programmatically.

Managing Application Services through Code

The main entry point to programmatically manage the application services is the SqlServices class from the System.Web.Management namespace. It's a pretty straight forward class with a number of static methods to install and uninstall application services and session state. As a simple example, here's how you can install all application services on a database called MyDatabase using a connection string defined elsewhere in your code:

SqlServices.Install("MyDatabase", SqlFeatures.All, connectionString);

Likewise, to remove the services again, simply call Uninstall:

SqlServices.Uninstall("MyDatabase", SqlFeatures.All, connectionString);

The second argument of the Install and Uninstall methods is the SqlFeatures enum which you can use to install or uninstall only some of the services:

SqlServices.Install("MyDatabase", 
    SqlFeatures.Membership | SqlFeatures.RoleManager, connectionString);

For some reason, both methods also want you to pass the name of the database. I am not sure why, as it could be inferred from the connection string that you also need to pass. I guess it's for scenarios where the connection string doesn't contain an Initial Catalog attribute.

Being a fan of the DRY principle, I created a simple wrapper class that uses a SqlConnectionStringBuilder that retrieves the database name from the connection string. In this example, the connection string comes from the web.config file's <connectionStrings /> element. The name of the database is then passed to the Install and Uninstall methods of the SqlServices class, like this:

public class ApplicationServices
{
  static string connectionString = WebConfigurationManager.
          ConnectionStrings["ApplicationServices"].ConnectionString;
  static SqlConnectionStringBuilder myBuilder = 
          new SqlConnectionStringBuilder(connectionString);

  public static void InstallServices(SqlFeatures sqlFeatures)
  {
    SqlServices.Install(myBuilder.InitialCatalog, sqlFeatures, connectionString);
  }

  public static void UninstallServices(SqlFeatures sqlFeatures)
  {
    SqlServices.Uninstall(myBuilder.InitialCatalog, sqlFeatures, connectionString);
  }
}

This code first retrieves the connection string with a name of ApplicationServices defined in web.config. it then feeds this connection string into the constructor of the SqlConnectionStringBuilder class. This class then parses the connection string and exposes relevant attributes of it through properties. For example, you can access the DataSource, the Password, the UserID and the InitialCatalog, which holds the name of the database. This initial catalog is then passed to the Install and Uninstall methods.

With this code, I can now install all application services in one fell swoop with the following code:

ApplicationServices.InstallServices(SqlFeatures.All);

In the zip file that you can download at the end of this article, you find a simple demo application. For the example to work, you already need to have an existing database called MembershipTest attached to your local copy of SQL Server Express. Update the connection string to target other servers or databases. You may want to extend this example a little further, making it a bit easier to reuse by making the connection string used configurable as well.

If you need an example of the configuration you need to add to web.config to address a database different than the default one, take a look at this article: Creating ASP.NET Users Programmatically

Downloads

Download the sample application for this article


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Thursday, August 05, 2010 1:04:37 AM embarus said:
Good article. It 's would be nice if you could show some custom provider with LINQ. I used to read it on web but difficult to understand. :)
On Thursday, August 05, 2010 6:14:13 AM Imar Spaanjaars said:
Hi embarus,

I am not sure I understand what you mean with "some custom provider with LINQ". Can you elaborate?

Cheers,

Imar
On Tuesday, October 05, 2010 9:47:32 AM Afshar Mohebbi said:
Man thanks imar, your solution saved me many times.

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.