MVC Starter Kits

MVC Starter Kits for ASP.NET

About the author

King Wilder, I'm an ASP.NET developer and I run and own a small web hosting company called Gizmo Beach.
E-mail me Send mail

Pages

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Web site Installer kit

ASP.NET web-based Site Installer


I had the need for this very thing so I thought I would write a small app that I can re-use on my many web-based applications.

Just as a side note... this is not MVC specific.  I know this is a Blog for MVC Starter Kits but this project can be used to install any web site.

What is the Web-based Site Installer?


solution explorer
This is an ASP.NET 2.0 AJAX web site application that you can plug into your web application (if it is meant to be distributed and installed by your customers) and have your customer be able to easily install the application through their browser.


solution explorer

There are more screen shots at the end of this blog post.

 

It's built on a simple ASP.NET Wizard control that gathers information needed to set up the application, usually database information, and then run several methods that do the following:

1)  Modify the web.config to add your connection string
2)  Create the database or use the one you selected
3)  Run scripts that add the database tables (of your choice) to the selected database
4)  Add the ASP.NET Membership tables to the database
5)  Creates Roles (Administrators, Users)
6)  Create an Administrator account based on user input
7)  Assigns that administrator account to the Administrators Role

When the process is completed, you can log on as the account you just created and verify that it all works!

This will work with SQL Server and SQL Server Express.  MySql is not implemented at this time.  Maybe in a future version.

Pre-requesites

1) You must have permission to the SQL Server instance you will be using
2) You must have already created the user for this setup.  In a shared web hosting situation, this would normally be handled through a control panel.  In the control panel you would setup your database and credentials and apply the necessary permissions.
3) The folder that contains the web.config (or external config file if you use the configSource attribute of the connection strings section), needs to have Read and Write permissions from NETWORK SERVICE.  Your control panel should be able to apply these permissions.  If they don't, contact your web host for help.

So assuming you have all the pre-requesites in place, let's continue.

Let's see how this works.  There are essentially 5 steps to the wizard.

1) Collect Server information - assign the server you will use, i.e.: localhost, localhost\SQLEXPRESS, sql.myserver.com, etc.
2) Choose database - you can choose from a list of available (SQL Server) databases, or enter the name of a new database
3) Enter Admin account info - enter the information for the admin account.  This will be entered into the ASP.NET 2.0 Membership tables.
4) Confirm your settings and execute the process.
5) Process completed!

So how does the installer know to go to the /install directory?

There's a small class that probes the web.config file and looks into the connectionStrings section.  If it finds this:

 

<connectionStrings>
<clear />
<add name="appConnection" connectionString="##NOT_IMPLEMENTED##" providerName="System.Data.SqlClient" />
</connectionStrings>

 

 ... then it knows that this is the first time the application is being run.

This is handled by the class, SetupUtility.  It contains a read-only property that returns a boolean value whether the connection string(s) are implemented.  It is called in the Global.asax file.

public class SetupUtility
{
// This string needs to added to the web.config/connectionStrings section on new applications.
// This is what tells the application that it's being used for the first time.
// You can put anything here, as long as it matches what is in the connectionString attribute value
// in the connectionStrings section of web.confg.
private const string NOTIMPLEMENTED = "##NOT_IMPLEMENTED##";

/// <summary>
/// Check all connection strings for ##NOT_IMPLEMENTED##. If it exists
/// in the connections strings section, it is the first time and we need
/// to redirect to the install folder.
/// </summary>
/// <returns></returns>
public static bool isFirstTime
{
get
{
bool firstTime = false;
ConnectionStringSettingsCollection connStrings = WebConfigurationManager.ConnectionStrings;
foreach (ConnectionStringSettings conn in connStrings)
{
if (conn.ConnectionString == NOTIMPLEMENTED)
{
firstTime = true;
break;
}
}
return firstTime;
}
}
}

 

It also contains a little generic helper method that can find controls within a starting control.  I use it in the AttachEventHandlerToFinishButton() method that tries to find the FinishButton in the wizInstall ASP.NET Wizard Control.

/// <summary>
/// You can return a control of a Type based on the ID and the starting Control.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="startingControl"></param>
/// <param name="id"></param>
/// <returns></returns>
public static T FindControl<T>(System.Web.UI.Control startingControl, string id) where T : System.Web.UI.Control
{
T found = null;
foreach (System.Web.UI.Control activeControl in startingControl.Controls)
{
found = activeControl as T;
if (found == null)
{
found = FindControl<T>(activeControl, id);
}
else if (string.Compare(id, found.ID, true) != 0)
{
found = null;
}
if (found != null)
{
break;
}
}
return found;
}

 

In the Global.asax file, this class is called in the Application_Start() event, and the isFirstTime property returns a Boolean value on whether the web.config connection strings section has been set.  If it still has the ##NOT_IMPLEMENTED## place holder, then it has not been set and the application redirects to the install page.

void Application_Start(object sender, EventArgs e) 
{
// Code that runs on application startup
if (SetupUtility.isFirstTime)
{
System.Web.HttpContext.Current.Response.Redirect("~/install/install.aspx", false);
}
}

 

That's what initiates the process.  Once the application re-starts, it won't go to the /install directory, or if it reads the connection strings section of the web.config file and all connection strings are set, then it will not go to the /install directory.


Install.aspx - code behind

All of the wizard processing occurs in the install.aspx code-behind.  The first few steps of the wizard collects the necessary information and the final button click runs the process.

This is the method that is called in the Finish button click event.

/// <summary>
/// Run all the functions to install the database tables and set the admin account.
/// </summary>
private void RunAll()
{
// If we are using an existing datbase, we don't need to create it.
if (!(bool)ViewState["UseExistingDb"])
{
// Create the Test database
if (!CreateDb()) throw new Exception("Error creating database!");
}

// Add the tables to the database
RunScripts(ViewState["DBName"].ToString());

// Add the ASPNETDB tables to the database using the SqlServices Install method.
// This will add the ASPNETDB tables to the same database as the application.
// NOTE: This method can ONLY be used for SQL Server. To point to MySql,
// you will need to create the database scripts for MySql and add them to
// the RunScripts method.
// Special thanks to the article by Peter Bromberg on the
// System.Web.Management.SqlServices.Install method at http://www.eggheadcafe.com/articles/20060529.asp
if (chkTrustedConnection.Checked)
{
// For SQL Server Trusted connections
System.Web.Management.SqlServices.Install(txtServerName.Text.Trim(), ViewState["DBName"].ToString(), System.Web.Management.SqlFeatures.All);
}
else
{
// For SQL Server
System.Web.Management.SqlServices.Install(txtServerName.Text.Trim(), ViewState["DbUserName"].ToString(), ViewState["DbPassword"].ToString(), ViewState["DBName"].ToString(), System.Web.Management.SqlFeatures.All);
}

// Create the Roles, Administrators, Users
if (!Roles.RoleExists(ADMINISTRATORS_ROLE)) Roles.CreateRole(ADMINISTRATORS_ROLE);
if (!Roles.RoleExists(USERS_ROLE)) Roles.CreateRole(USERS_ROLE);

// Create the Admin User
MembershipCreateStatus status = MembershipCreateStatus.UserRejected;
MembershipUser user = Membership.CreateUser(txtAdminUserName.Text.Trim(), ViewState["AdminPassword"].ToString(), txtAdminEmail.Text.Trim(),
txtSecretQuestion.Text.Trim(), txtSecretAnswer.Text.Trim(), true, out status);

// Assign the Admin user to the Administrators role
if (status == MembershipCreateStatus.Success)
{
Roles.AddUserToRole(txtAdminUserName.Text, ADMINISTRATORS_ROLE);
}

}

 

Let's go over the steps in the RunAll() method.  The first "if" statement checks whether the selected database already exists, if it does, we simply bypass this method.  Otherwise, we create the database.

The RunScripts() method takes the name of the database and runs any number of SQL scripts (that you provide) to create tables in your database, import sample data, drop tables, or whatever you need to do. 

 

/// <summary>
/// Run SQL scripts to create the tables and any other sql scripts.
/// </summary>
/// <param name="dbName"></param>
private void RunScripts(string dbName)
{
//Tables
string[] tableStatements = GetScriptStatements(File.ReadAllText(Server.MapPath(SCRIPT_TABLES), new System.Text.UTF8Encoding()));
ExecuteStatements(tableStatements, dbName);

// Add other sql statements here... such as... !!! Notice the string array variable name is unique
// and it gets passed into the ExecuteStatements method.
//string[] newStatements = GetScriptStatements(File.ReadAllText(Server.MapPath(["some other sql scripts"]), new System.Text.UTF8Encoding()));
//ExecuteStatements(newStatements, dbName);

// Add other sql statements here... such as...
//string[] moreStatements = GetScriptStatements(File.ReadAllText(Server.MapPath(["even more sql scripts"]), new System.Text.UTF8Encoding()));
//ExecuteStatements(moreStatements, dbName);
}

 

Simply by adding more lines of code as shown above, you can run as many SQL scripts as you need.

IMPORTANT!!! If you run more than one sql script, each string array variable needs to be unique!

Here are the three variables in this example:

1) string[] tableStatements = GetScriptStatements(...)
2) string[] newStatements = GetScriptStatements(...)
3) string[] moreStatements = GetScriptStatements(...)

Notice that these are all unique and they get passed into the ExecuteStatements method.  If you just repeat tableStatements, it will generate an error.

The next method call is the interesting one.  System.Web.Management.SqlServices.Install().  What is this?  It's a little known class that does essentially what "aspnet_regsql.exe" does, except you can handle these matters programmatically.  For more information about this, go here, http://msdn2.microsoft.com/en-us/library/system.web.management.sqlservices.install.aspx.

 

if (chkTrustedConnection.Checked)
{
// For SQL Server Trusted connections
System.Web.Management.SqlServices.Install(txtServerName.Text.Trim(), ViewState["DBName"].ToString(), System.Web.Management.SqlFeatures.All);
}
else
{
// For SQL Server
System.Web.Management.SqlServices.Install(txtServerName.Text.Trim(), ViewState["DbUserName"].ToString(), ViewState["DbPassword"].ToString(), ViewState["DBName"].ToString(), System.Web.Management.SqlFeatures.All);
}

 

If you didn't want to use this class, you could simply gather the SQL scripts for the Membership tables and place the sql scripts in the /install/installscripts folder and call them in the RunScripts method.  It will accomplish pretty much the same thing.

You'll notice there is one for SQL Server trusted connections, and one that uses all necessary information.  Obviously the trusted connection overload does not require credentials.

After that, we create the roles, you can add as many roles here that you need, I'm only creating the Administrators and Users roles.

 

// Create the Roles, Administrators, Users
if (!Roles.RoleExists(ADMINISTRATORS_ROLE)) Roles.CreateRole(ADMINISTRATORS_ROLE);
if (!Roles.RoleExists(USERS_ROLE)) Roles.CreateRole(USERS_ROLE);

 

Then we create the Admin user account based on the information collected in the wizard.  And then we assign the newly created admin account to the Administrators role.

 

// Create the Admin User
MembershipCreateStatus status = MembershipCreateStatus.UserRejected;
MembershipUser user = Membership.CreateUser(txtAdminUserName.Text.Trim(), ViewState["AdminPassword"].ToString(), txtAdminEmail.Text.Trim(),
txtSecretQuestion.Text.Trim(), txtSecretAnswer.Text.Trim(), true, out status);

// Assign the Admin user to the Administrators role
if (status == MembershipCreateStatus.Success)
{
Roles.AddUserToRole(txtAdminUserName.Text, ADMINISTRATORS_ROLE);
}

 

 That's it!

It works pretty nicely and I hope you get some value from it.

Ok, one more thing... How do you integrate this into your own web site application?

Simple, just do the following and in seconds you can have an installer for your application:

  1. Copy the SetupUtility.cs file to your web site App_Code folder, or if you have a separate class library project, add the class to that project.
  2. Copy the Install folder in your web site.
  3. Create whatever database table sql scripts you need to run for your application, and add them to the /install/installscripts folder.
  4. Add the if statement to the Global.asax file.
  5. Prepare your web.config/connectionStrings section and change the connectionString attribute value to ##NOT_IMPLEMENTED##.

That should do it!  This should be just a starter example for you.  You can extend this any way you deem necessary for your application.

If you have any questions or find any bugs, please post them here or in my Forum.

You can download the sample web site here: DBInstallSite.zip (22 KB)

Thank you,

King Wilder

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET
Posted by Admin on Tuesday, July 08, 2008 3:28 AM
Permalink | Comments (65) | Post RSSRSS comment feed

Related posts

Comments

databasemanagementconsulting.com

Tuesday, July 08, 2008 4:36 AM

pingback

Pingback from databasemanagementconsulting.com

Database Management » Blog Archive » Web site Installer kit

ab110.com

Wednesday, July 09, 2008 3:42 PM

pingback

Pingback from ab110.com

Always 英文技术文章参照( 五 ){ UpdateTime:2008-7-10; } My article in the cnblogs - cnblogs.com

busby seo test us

Saturday, January 10, 2009 1:50 AM

busby seo test

it's a great code, thank you for sharing Smile

Busby Test us

Friday, January 16, 2009 10:26 AM

Busby Test

Yes, thank you very much.
regrads.

Hamzah Maru us

Sunday, January 18, 2009 8:41 AM

Hamzah Maru

good info, thanks for sharing this valuable info.

Busby SEO Test us

Monday, January 26, 2009 9:06 PM

Busby SEO Test

Very good information

busby seo us

Wednesday, January 28, 2009 9:13 PM

busby seo

hi, i am here again, waiting for the next post.

cell phone gps us

Sunday, February 01, 2009 9:56 PM

cell phone gps

Very informative website and .... good posts.

King Wilder us

Monday, February 02, 2009 2:18 AM

King Wilder

Thank you, I'm glad this post helps.

gmat ua

Thursday, February 26, 2009 11:41 AM

gmat

good info, thanks for sharing this valuable info.

jammer sk

Thursday, February 26, 2009 11:42 AM

jammer

Very informative website and .... good posts.

San Antonio Movers sk

Thursday, February 26, 2009 11:42 AM

San Antonio Movers

Yes, thank you very much.
regrads.

Piano Mover at

Thursday, February 26, 2009 11:44 AM

Piano Mover

it's a great code, thank you for sharing

titi us

Saturday, February 28, 2009 5:36 PM

titi

Somebody can help me with the issue of the roles. When i hit the finish button an error message appears and says:"The Role Manager feature has not been enabled."
Does somebody can help me and provide me a information.
Thank you

titi us

Saturday, February 28, 2009 6:07 PM

titi

don`t worry! i did it

King Wilder us

Sunday, March 01, 2009 4:10 AM

King Wilder

titi,

In order for this to work and create the ASPNETDB database, the Roles and Membership sections of the web.config need to be set. Add those sections and it should work.

I see you got it to work, good work!

model us

Friday, March 20, 2009 7:04 PM

model

good article, I like this website

Pink Stuff ph

Sunday, March 29, 2009 9:43 AM

Pink Stuff

nice post, thanks for sharing and keep on posting.

koo us

Sunday, March 29, 2009 9:44 AM

koo

very useful post, thanks for sharing.

Louisiana movers mo

Monday, April 06, 2009 9:04 AM

Louisiana movers

great post
thanks alot

tukang nggame us

Tuesday, April 07, 2009 11:26 PM

tukang nggame

Great post

weightloss regimens us

Thursday, April 09, 2009 11:48 PM

weightloss regimens

Thanks for your sharing and waiting to see your future posts.

Kampanye Damai Pemilu Indonesia 2009 us

Monday, April 13, 2009 8:26 PM

Kampanye Damai Pemilu Indonesia 2009

from here i know something that i want to know..
thanks for this usefull informations..

Kampanye Damai Pemilu Indonesia 2009 us

Tuesday, April 14, 2009 6:41 PM

Kampanye Damai Pemilu Indonesia 2009

..and even look like difficult to implemented, that's a nice steps, thanks..

Seminyak Villas ru

Wednesday, April 15, 2009 2:52 PM

Seminyak Villas

waiting for your next post....

bureacratic leadership gb

Monday, April 20, 2009 2:59 AM

bureacratic leadership

Hehe nice little screenshots there, i think its good to be nice and relaxed and not get too bureacratic about things.

Oklahoma movers be

Monday, April 20, 2009 7:46 AM

Oklahoma movers

great post
like it sir
thank u

Minnesota movers fo

Monday, April 20, 2009 7:47 AM

Minnesota movers

thank u
we love u all

Pinay Showbiz us

Thursday, April 23, 2009 2:13 PM

Pinay Showbiz

I just want to say thank you for the information that you have shared. It was really useful!

tukang nggame gb

Saturday, April 25, 2009 3:56 PM

tukang nggame

very useful information

Leadership Training gb

Monday, April 27, 2009 2:41 AM

Leadership Training

Thankyou for writing this, I have to say I'm rather inspired to start training up my writing skills and after the training write my own blog post and try and hit the same sort of tone.

Leadership Training gb

Monday, April 27, 2009 2:42 AM

Leadership Training

Thankyou for writing this, I have to say I'm rather inspired to start training up my writing skills and after the training write my own blog post and try and hit the same sort of tone.

Electroplating gb

Monday, April 27, 2009 3:44 AM

Electroplating

What a terrific blog post, I wish I could write as well as you do. Unfortunately with a background in electroplating I'm hardly a poetic. Maybe if I spend time practicing writing, I can shun my electoplating career and become a writer online? Haha, a bit of a fantasy maybe.

tukang nggame

Saturday, May 02, 2009 5:17 PM

tukang nggame

Nice posting

le vin us

Friday, May 08, 2009 11:25 PM

le vin

nice tips!!

Cheshire Dentists gb

Tuesday, June 02, 2009 11:43 PM

Cheshire Dentists

The most attractive thing about this code are they are very simple created means their is no any bugs.

Make a Legal Will gb

Wednesday, June 10, 2009 10:21 PM

Make a Legal Will

I have post this code in my application and it's really working.

t-mac us

Sunday, June 14, 2009 6:49 PM

t-mac

Could you also post a link of the source code. Smile

King Wilder us

Monday, June 15, 2009 2:46 AM

King Wilder

t-mac, the link is at the end of the article. Just before all of the images.

Thanks.

Tukang Nggame us

Friday, June 19, 2009 7:16 AM

Tukang Nggame

thanks for the great article, this really nice blog

franchises for sale us

Friday, June 19, 2009 9:02 AM

franchises for sale

hmmmm i'm hungry. Ooops, focus matthew focus matthew focus. Just browsing, thinking of food and browsing. Post some more Smile MunchMunch

best keno online games ca

Sunday, June 21, 2009 5:22 PM

best keno online games

This blog Is very informative , I am really pleased to post my comment on this blog . It helped me with ocean of knowledge so I really believe you will do much better in the future . Good job web master.

SEO us

Monday, June 22, 2009 10:02 PM

SEO

Nice article.The code works fine and is a good starting point for me making a custom module.Thanks for the module...

storage us

Friday, June 26, 2009 2:20 PM

storage

Very helpful and informative post. Not many people will post it for free. Thanks for sharing it.

SEO 対策 沖縄 ホームページ制作 th

Sunday, June 28, 2009 1:48 AM

SEO 対策 沖縄 ホームページ制作

wow. the step by step tutorial was so helpful!

tukang nggame us

Monday, June 29, 2009 7:39 PM

tukang nggame

great article

RUSLI zainal sang Visioner us

Friday, July 03, 2009 11:22 AM

RUSLI zainal sang Visioner

I like your browser

affordable college degree us

Monday, July 06, 2009 9:29 PM

affordable college degree

Very helpful and informative post. Not many people will post it for free. Thanks for sharing it.

stop dreaming start action

Tuesday, July 07, 2009 11:08 PM

stop dreaming start action

nice kit

moving at

Wednesday, July 08, 2009 7:13 AM

moving

we love u all

jammer by

Wednesday, July 08, 2009 7:13 AM

jammer

love u all

Online Poker

Thursday, July 09, 2009 6:33 PM

Online Poker

The site installer was very useful for me as I had to do the samething

Online GED Test us

Friday, July 10, 2009 3:57 PM

Online GED Test

I had to do the samething

Home School us

Friday, July 10, 2009 3:57 PM

Home School

nice kit

Online degree us

Friday, July 10, 2009 3:59 PM

Online degree

The site installer was very useful for me as I had to do the samething

online associate Degree us

Friday, July 10, 2009 4:00 PM

online associate Degree

we love u all

stop dreaming start action id

Sunday, July 12, 2009 1:01 PM

stop dreaming start action

thank you for your tutorial. that a nice tutorial

Emo Clothes us

Monday, July 13, 2009 5:08 PM

Emo Clothes

Thankyou for writing this, I have to say I'm rather inspired to start training up my writing skills and after the training write my own blog post and try and hit the same sort of tone. Emo Clothes

stop dreaming start action id

Tuesday, July 14, 2009 4:06 PM

stop dreaming start action

thanks for post i really like it

Veyton Templates de

Sunday, July 19, 2009 8:54 PM

Veyton Templates

cool, thanks for this step by step turorial.

web design us

Sunday, July 19, 2009 11:27 PM

web design

Thanks for this information !

taschenlampe de

Friday, July 24, 2009 8:53 PM

taschenlampe

Very helpful and informative post

Mens Wear us

Saturday, July 25, 2009 3:12 AM

Mens Wear

Thank you for sharing this buddy. It really help.

Make Money Online us

Monday, July 27, 2009 6:59 AM

Make Money Online

This is great, I never knew about the site installer.

sulumits retsambew us

Monday, July 27, 2009 3:09 PM

sulumits retsambew

very useful info. thanks