在许多部署环境中,自动化配置向导是一个极为有用的工具。虽然可以使用Web部署项目,但通常需要在服务器上运行安装程序,这在共享主机环境中可能并不适用。本文介绍的向导允许通过FTP将应用程序上传到远程服务器,然后从Web浏览器启动配置向导。
本文提供的C#版本向导被封装在单一页面中,以便能够轻松自定义。
当用户首次打开未设置的应用程序页面时,他们会看到以下屏幕:
这是因为以下代码尝试使用LINQ to SQL数据上下文连接到数据库,该上下文使用web.config中的数据库连接设置。如果能够连接,它将尝试计算Users表中的记录数。数据库可能存在,但Users表可能不存在。两者都需要存在才能认为设置完成。可以插入代码以检查表中的版本号。这将允许向导在升级情况下运行。
以下是处理页面加载的C#代码:
protected void Page_Load(object sender, EventArgs e)
{
lnkSetup.Visible = !CanConnectToDatabase();
lnkWebApplication.Visible = !lnkSetup.Visible;
}
private bool CanConnectToDatabase()
{
// 此方法返回true,如果数据库存在并且表已创建
bool CanConnect = true;
try
{
DataClassesDataContext DataClassesDataContext = new DataClassesDataContext();
var result = from Users in DataClassesDataContext.Users select Users;
int intCount = result.Count();
}
catch (Exception e)
{
string strError = e.Message;
CanConnect = false;
}
return CanConnect;
}
如果数据库连接成功,向导将检查文件和文件夹的权限。
protected void btnCheckPermissions_Click(object sender, EventArgs e)
{
int intValidItems = 0;
blPermissions.Items.Clear();
// 文件夹创建权限检查
ListItem permissionItem = new ListItem();
permissionItem.Text = String.Format("Folder Create - {0}", ((VerifyFolderCreate()) ? "Passed" : "Failed"));
permissionItem.Enabled = ((permissionItem.Text.Contains("Passed")) ? true : false);
blPermissions.Items.Add(permissionItem);
intValidItems = intValidItems + ((permissionItem.Text.Contains("Passed")) ? 1 : 0);
// 其他权限检查...
lblPermissionCheck.Text = String.Format("Permissions {0}", ((intValidItems == 4) ? "Passed" : "Failed"));
lblPermissionCheck.BackColor = ((intValidItems == 4) ? Color.Green : Color.Red);
// 显示继续按钮?
btnPermissionsNext.Visible = ((intValidItems == 4) ? true : false);
}
接下来,用户可以配置数据库连接并测试它:
private bool CanConnectToDatabase()
{
string strUserInfo = (!chkIntegrated.Checked) ? String.Format("Persist Security Info=True;User ID={0};Password={1}", this.txtUserId.Text, this.txtPassword.Text) : "Integrated Security=True";
string strConnection = String.Format("Data Source={0};Initial Catalog={1};{2}", this.txtServer.Text, this.txtDatabase.Text, strUserInfo);
DataClassesDataContext DataClassesDataContext = new DataClassesDataContext(strConnection);
return DataClassesDataContext.DatabaseExists();
}
如果连接存在,它将被存储在web.config中:
if (boolCanConnectToDatabase)
{
System.Configuration.Configuration rootWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
System.Configuration.ConnectionStringSettings connString;
if (rootWebConfig.ConnectionStrings.ConnectionStrings.Count > 0)
{
connString = rootWebConfig.ConnectionStrings.ConnectionStrings["WebInstallerConnectionString"];
if (connString != null)
{
connString.ConnectionString = strConnection;
rootWebConfig.Save();
}
}
}
向导的下一页检查Users表是否已经创建(用户可能只是运行向导来修复web.config后移动SQL服务器)。如果表存在,它允许用户移动到下一步。如果不存在,它指示继续按钮将运行.sql设置脚本。
#region Database Set-up
private void SetupDatabase()
{
DatabaseReady = TableExists();
lblDatabaseSetup.Text = (DatabaseReady) ? "The Database is already set-up. Click continue." : "Click the Continue button to run the database set-up scripts.";
}
private bool TableExists()
{
bool CanConnect = true;
try
{
DataClassesDataContext DataClassesDataContext = new DataClassesDataContext();
var result = from Users in DataClassesDataContext.Users select Users;
int intCount = result.Count();
}
catch (Exception e)
{
string strError = e.Message;
CanConnect = false;
}
return CanConnect;
}
protected void btnDatabaseSetupNext_Click(object sender, EventArgs e)
{
if (!TableExists())
{
try
{
string strSqlScript = GetSQLScript();
DataClassesDataContext DataClassesDataContext = new DataClassesDataContext();
DataClassesDataContext.ExecuteCommand(strSqlScript);
}
catch (Exception ex)
{
lblDatabaseSetup.Text = ex.Message;
return;
}
}
mvSetupWizard.SetActiveView(vwComplete);
}
private String GetSQLScript()
{
string strSQLScript;
string strFilePath = MapPath("~/SQLScripts/Setup.sql");
StreamReader reader = new StreamReader(strFilePath);
strSQLScript = reader.ReadToEnd();
reader.Close();
reader = null;
return strSQLScript;
}
#endregion
向导的最后一页包含一个按钮,将用户返回到应用程序的第一页:
现在,程序检测到应用程序已正确设置: