Giving the install/upgrade a bit of TLC.

Fixes U4-1520
This commit is contained in:
Morten Christensen
2013-01-28 14:01:38 -01:00
parent 3907ea435a
commit 5d0aced9a7
17 changed files with 279 additions and 128 deletions

View File

@@ -16,6 +16,8 @@ echo This file is only here so that the containing folder will be included in th
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\media\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\scripts\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\usercontrols\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\Partials\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\MacroPartials\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\xslt\dummy.txt
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%

View File

@@ -26,8 +26,9 @@ namespace Umbraco.Core
private bool _configured;
private string _connectionString;
private string _providerName;
private DatabaseSchemaResult _result;
internal DatabaseContext(IDatabaseFactory factory)
internal DatabaseContext(IDatabaseFactory factory)
{
_factory = factory;
}
@@ -245,7 +246,7 @@ namespace Umbraco.Core
Initialize(providerName);
}
else if (ConfigurationManager.AppSettings.ContainsKey(GlobalSettings.UmbracoConnectionName))
else if (ConfigurationManager.AppSettings.ContainsKey(GlobalSettings.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName]) == false)
{
//A valid connectionstring does not exist, but the legacy appSettings key was found, so we'll reconfigure the conn.string.
var legacyConnString = ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName];
@@ -308,10 +309,13 @@ namespace Umbraco.Core
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
return new DatabaseSchemaResult();
var database = new UmbracoDatabase(_connectionString, ProviderName);
var dbSchema = new DatabaseSchemaCreation(database);
var result = dbSchema.ValidateSchema();
return result;
if (_result == null)
{
var database = new UmbracoDatabase(_connectionString, ProviderName);
var dbSchema = new DatabaseSchemaCreation(database);
_result = dbSchema.ValidateSchema();
}
return _result;
}
internal Result CreateDatabaseSchemaAndDataOrUpgrade()
@@ -332,11 +336,13 @@ namespace Umbraco.Core
var database = new UmbracoDatabase(_connectionString, ProviderName);
var schemaResult = ValidateDatabaseSchema();
var installedVersion = schemaResult.DetermineInstalledVersion();
string message;
//If Configuration Status is empty and the determined version is "empty" its a new install - otherwise upgrade the existing
if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus) && installedVersion.Equals(new Version(0, 0, 0)))
{
database.CreateDatabaseSchema();
message = "Installation completed!";
}
else
{
@@ -346,13 +352,28 @@ namespace Umbraco.Core
var targetVersion = UmbracoVersion.Current;
var runner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
var upgraded = runner.Execute(database, true);
message = "Upgrade completed!";
}
return new Result { Message = "Installation completed!", Success = true, Percentage = "100" };
return new Result { Message = message, Success = true, Percentage = "100" };
}
catch (Exception ex)
{
return new Result { Message = ex.Message, Success = false, Percentage = "90" };
LogHelper.Info<DatabaseContext>("Database configuration failed with the following error and stack trace: " + ex.Message + "\n" + ex.StackTrace);
if (_result != null)
{
LogHelper.Info<DatabaseContext>("The database schema validation produced the following summary: \n" + _result.GetSummary());
}
return new Result
{
Message =
"The database configuration failed with the following message: " + ex.Message +
"\n Please check log file for addtional information (can be found in '/App_Data/Logs/UmbracoTraceLog.txt')",
Success = false,
Percentage = "90"
};
}
}

View File

@@ -132,6 +132,11 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
result.Errors.Add(new Tuple<string, string>("Column", column));
}
//MySql doesn't conform to the "normal" naming of constraints, so there is currently no point in doing these checks.
//NOTE: At a later point we do other checks for MySql, but ideally it should be necessary to do special checks for different providers.
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider)
return result;
//Check constraints in configured database against constraints in schema
var constraintsInDatabase = SyntaxConfig.SqlSyntaxProvider.GetConstraintsPerColumn(_database).DistinctBy(x => x.Item3).ToList();
var foreignKeysInDatabase = constraintsInDatabase.Where(x => x.Item3.StartsWith("FK_")).Select(x => x.Item3).ToList();

View File

@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Initial
{
@@ -59,7 +61,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
return new Version(4, 7, 0);
}
return new Version(4, 10, 0);
return new Version(4, 9, 0);
}
return new Version(0, 0, 0);
@@ -71,7 +73,48 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
/// <returns>A string containing a human readable string with a summary message</returns>
public string GetSummary()
{
return string.Empty;
var sb = new StringBuilder();
if (Errors.Any() == false)
{
sb.AppendLine("The database schema validation didn't find any errors.");
return sb.ToString();
}
//Table error summary
if (Errors.Any(x => x.Item1.Equals("Table")))
{
sb.AppendLine("The following tables were found in the database, but are not in the current schema:");
sb.AppendLine(string.Join(",", Errors.Where(x => x.Item1.Equals("Table")).Select(x => x.Item2)));
sb.AppendLine(" ");
}
//Column error summary
if (Errors.Any(x => x.Item1.Equals("Column")))
{
sb.AppendLine("The following columns were found in the database, but are not in the current schema:");
sb.AppendLine(string.Join(",", Errors.Where(x => x.Item1.Equals("Column")).Select(x => x.Item2)));
sb.AppendLine(" ");
}
//Constraint error summary
if (Errors.Any(x => x.Item1.Equals("Constraint")))
{
sb.AppendLine("The following constraints (Primary Keys, Foreign Keys and Indexes) were found in the database, but are not in the current schema:");
sb.AppendLine(string.Join(",", Errors.Where(x => x.Item1.Equals("Constraint")).Select(x => x.Item2)));
sb.AppendLine(" ");
}
//Unknown constraint error summary
if (Errors.Any(x => x.Item1.Equals("Unknown")))
{
sb.AppendLine("The following unknown constraints (Primary Keys, Foreign Keys and Indexes) were found in the database, but are not in the current schema:");
sb.AppendLine(string.Join(",", Errors.Where(x => x.Item1.Equals("Unknown")).Select(x => x.Item2)));
sb.AppendLine(" ");
}
if (SyntaxConfig.SqlSyntaxProvider is MySqlSyntaxProvider)
{
sb.AppendLine("Please note that the constraints could not be validated because the current dataprovider is MySql.");
}
return sb.ToString();
}
}
}

View File

@@ -42,23 +42,86 @@ namespace Umbraco.Core.Persistence.SqlSyntax
public override IEnumerable<string> GetTablesInSchema(Database db)
{
var items = db.Fetch<dynamic>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");
return items.Select(x => x.TABLE_NAME).Cast<string>().ToList();
List<string> list;
try
{
db.OpenSharedConnection();
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @TableSchema",
new {TableSchema = db.Connection.Database});
list = items.Select(x => x.TABLE_NAME).Cast<string>().ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
public override IEnumerable<ColumnInfo> GetColumnsInSchema(Database db)
{
return new List<ColumnInfo>();
List<ColumnInfo> list;
try
{
db.OpenSharedConnection();
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @TableSchema",
new {TableSchema = db.Connection.Database});
list =
items.Select(
item =>
new ColumnInfo(item.TABLE_NAME, item.COLUMN_NAME, item.ORDINAL_POSITION, item.COLUMN_DEFAULT,
item.IS_NULLABLE, item.DATA_TYPE)).ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
public override IEnumerable<Tuple<string, string>> GetConstraintsPerTable(Database db)
{
return new List<Tuple<string, string>>();
List<Tuple<string, string>> list;
try
{
//Does not include indexes and constraints are named differently
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = @TableSchema",
new {TableSchema = db.Connection.Database});
list = items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
public override IEnumerable<Tuple<string, string, string>> GetConstraintsPerColumn(Database db)
{
return new List<Tuple<string, string, string>>();
List<Tuple<string, string, string>> list;
try
{
//Does not include indexes and constraints are named differently
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = @TableSchema",
new {TableSchema = db.Connection.Database});
list =
items.Select(
item =>
new Tuple<string, string, string>(item.TABLE_NAME, item.COLUMN_NAME, item.CONSTRAINT_NAME))
.ToList();
}
finally
{
db.CloseSharedConnection();
}
return list;
}
public override bool DoesTableExist(Database db, string tableName)

View File

@@ -72,7 +72,7 @@ namespace Umbraco.Core.Persistence.SqlSyntax
{
var items =
db.Fetch<dynamic>(
"SELECT TABLE_NAME, CONSTRAINT_NAME FROM SELECT * FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE");
"SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE");
return items.Select(item => new Tuple<string, string>(item.TABLE_NAME, item.CONSTRAINT_NAME)).ToList();
}

View File

@@ -1228,13 +1228,12 @@ namespace Umbraco.Core.Services
_publishingStrategy.PublishingFinalized(content);
//We need to check if children and their publish state to ensure that we republish content that was previously published
if (HasChildren(content.Id))
if (omitCacheRefresh == false && HasChildren(content.Id))
{
var children = GetDescendants(content);
var shouldBeRepublished = children.Where(child => HasPublishedVersion(child.Id));
if (omitCacheRefresh == false)
_publishingStrategy.PublishingFinalized(shouldBeRepublished, false);
_publishingStrategy.PublishingFinalized(shouldBeRepublished, false);
}
Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId, content.Id);

View File

@@ -76,6 +76,8 @@
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0"/>
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
<remove invariant="MySql.Data.MySqlClient"/>
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.6.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>

View File

@@ -313,7 +313,9 @@
<Compile Include="Routing\UmbracoModuleTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="App.config">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
<None Include="TestHelpers\ExamineHelpers\umbraco.config" />
<None Include="unit-test-log4net.config">

View File

@@ -269,10 +269,42 @@
<!-- installing umbraco -->
<div class="tab install-tab" id="datebase-tab">
<div class="container">
<h1>Installing Umbraco</h1>
<p>
The Umbraco database is being configured. This process populates your chosen database with a blank Umbraco instance.
</p>
<asp:PlaceHolder ID="installProgress" runat="server" Visible="True">
<div class="progress-status-container">
<h1>Installing Umbraco</h1>
<p>
The Umbraco database is being configured. This process populates your chosen database with a blank Umbraco instance.
</p>
</div>
<div class="result-status-container" style="display: none;">
<h1>Database installed</h1>
<div class="success">
<p>
Umbraco
<%=UmbracoVersion.Current.ToString(3)%>
has now been copied to your database. Press <b>Continue</b> to proceed.
</p>
</div>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="upgradeProgress" runat="server" Visible="False">
<div class="progress-status-container">
<h1>Upgrading Umbraco</h1>
<p>
The Umbraco database is being configured. This process upgrades your Umbraco database.
</p>
</div>
<div class="result-status-container" style="display: none;">
<h1>Database upgraded</h1>
<div class="success">
<p>
Your database has been upgraded to version:
<%=UmbracoVersion.Current.ToString(3)%>.<br />
Press <b>Continue</b> to proceed.
</p>
</div>
</div>
</asp:PlaceHolder>
<div class="loader">
<div class="hold">
<div class="progress-bar">
@@ -310,6 +342,8 @@
if (json.Success) {
$(".btn-box").show();
$('.ui-progressbar-value').css("background-image", "url(../umbraco_client/installer/images/pbar.gif)");
$(".result-status-container").show();
$(".progress-status-container").hide();
} else {
$(".btn-continue").hide();
$(".btn-back").show();
@@ -320,32 +354,4 @@
});
</script>
</asp:PlaceHolder>
<asp:Panel ID="confirms" runat="server" Visible="False">
<asp:PlaceHolder ID="installConfirm" runat="server" Visible="False">
<h1>Database installed</h1>
<div class="success">
<p>
Umbraco
<%=UmbracoVersion.Current.ToString(3)%>
has now been copied to your database. Press <b>Continue</b> to proceed.
</p>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="upgradeConfirm" runat="server" Visible="False">
<h1>Database upgraded</h1>
<div class="success">
<p>
Your database has been upgraded to version:
<%=UmbracoVersion.Current.ToString(3)%>.<br />
Press <b>Continue</b> to proceed.
</p>
</div>
</asp:PlaceHolder>
<!-- btn box -->
<footer class="btn-box" style="display: none;">
<div class="t">&nbsp;</div>
<asp:LinkButton class="btn-step btn btn-continue" runat="server" OnClick="gotoNextStep"><span>Continue</span></asp:LinkButton>
</footer>
</asp:Panel>
</asp:PlaceHolder>

View File

@@ -66,7 +66,7 @@
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0"/>
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
<remove invariant="MySql.Data.MySqlClient"/>
<remove invariant="MySql.Data.MySqlClient"/>
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.6.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>

View File

@@ -41,7 +41,7 @@ namespace umbraco.presentation.install.steps.Definitions
//Even though the ConfigurationStatus is blank we try to determine the version if we can connect to the database
var result = ApplicationContext.Current.DatabaseContext.ValidateDatabaseSchema();
var determinedVersion = result.DetermineInstalledVersion();
if(determinedVersion.Equals(new Version(0, 0, 0)))
if (determinedVersion.Equals(new Version(0, 0, 0)))
return false;
return UmbracoVersion.Current < determinedVersion;

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using umbraco.cms.businesslogic.installer;
using umbraco.cms.businesslogic.installer;
namespace umbraco.presentation.install.steps.Definitions
{

View File

@@ -269,10 +269,42 @@
<!-- installing umbraco -->
<div class="tab install-tab" id="datebase-tab">
<div class="container">
<h1>Installing Umbraco</h1>
<p>
The Umbraco database is being configured. This process populates your chosen database with a blank Umbraco instance.
</p>
<asp:PlaceHolder ID="installProgress" runat="server" Visible="True">
<div class="progress-status-container">
<h1>Installing Umbraco</h1>
<p>
The Umbraco database is being configured. This process populates your chosen database with a blank Umbraco instance.
</p>
</div>
<div class="result-status-container" style="display: none;">
<h1>Database installed</h1>
<div class="success">
<p>
Umbraco
<%=UmbracoVersion.Current.ToString(3)%>
has now been copied to your database. Press <b>Continue</b> to proceed.
</p>
</div>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="upgradeProgress" runat="server" Visible="False">
<div class="progress-status-container">
<h1>Upgrading Umbraco</h1>
<p>
The Umbraco database is being configured. This process upgrades your Umbraco database.
</p>
</div>
<div class="result-status-container" style="display: none;">
<h1>Database upgraded</h1>
<div class="success">
<p>
Your database has been upgraded to version:
<%=UmbracoVersion.Current.ToString(3)%>.<br />
Press <b>Continue</b> to proceed.
</p>
</div>
</div>
</asp:PlaceHolder>
<div class="loader">
<div class="hold">
<div class="progress-bar">
@@ -310,6 +342,8 @@
if (json.Success) {
$(".btn-box").show();
$('.ui-progressbar-value').css("background-image", "url(../umbraco_client/installer/images/pbar.gif)");
$(".result-status-container").show();
$(".progress-status-container").hide();
} else {
$(".btn-continue").hide();
$(".btn-back").show();
@@ -320,32 +354,4 @@
});
</script>
</asp:PlaceHolder>
<asp:Panel ID="confirms" runat="server" Visible="False">
<asp:PlaceHolder ID="installConfirm" runat="server" Visible="False">
<h1>Database installed</h1>
<div class="success">
<p>
Umbraco
<%=UmbracoVersion.Current.ToString(3)%>
has now been copied to your database. Press <b>Continue</b> to proceed.
</p>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="upgradeConfirm" runat="server" Visible="False">
<h1>Database upgraded</h1>
<div class="success">
<p>
Your database has been upgraded to version:
<%=UmbracoVersion.Current.ToString(3)%>.<br />
Press <b>Continue</b> to proceed.
</p>
</div>
</asp:PlaceHolder>
<!-- btn box -->
<footer class="btn-box" style="display: none;">
<div class="t">&nbsp;</div>
<asp:LinkButton class="btn-step btn btn-continue" runat="server" OnClick="gotoNextStep"><span>Continue</span></asp:LinkButton>
</footer>
</asp:Panel>
</asp:PlaceHolder>

View File

@@ -71,8 +71,29 @@ namespace umbraco.presentation.install.steps
{
// Does the user have to enter a connection string?
if (settings.Visible && !Page.IsPostBack)
ShowDatabaseSettings();
{
//If the connection string is already present in web.config we don't need to show the settings page and we jump to installing/upgrading.
if (
ConfigurationManager.ConnectionStrings[
Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName] == null
||
string.IsNullOrEmpty(
ConfigurationManager.ConnectionStrings[
Umbraco.Core.Configuration.GlobalSettings.UmbracoConnectionName].ConnectionString))
{
installProgress.Visible = true;
upgradeProgress.Visible = false;
ShowDatabaseSettings();
}
else
{
installProgress.Visible = false;
upgradeProgress.Visible = true;
settings.Visible = false;
installing.Visible = true;
}
}
}
/// <summary>

View File

@@ -220,30 +220,21 @@ namespace umbraco.presentation.install.steps {
protected global::System.Web.UI.WebControls.PlaceHolder installing;
/// <summary>
/// confirms control.
/// installProgress control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel confirms;
protected global::System.Web.UI.WebControls.PlaceHolder installProgress;
/// <summary>
/// installConfirm control.
/// upgradeProgress control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder installConfirm;
/// <summary>
/// upgradeConfirm control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder upgradeConfirm;
protected global::System.Web.UI.WebControls.PlaceHolder upgradeProgress;
}
}

View File

@@ -1,14 +1,8 @@
using umbraco;
using System;
using Umbraco.Core;
namespace umbraco.presentation.install
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
/// <summary>
/// Summary description for welcome.
/// </summary>
@@ -17,24 +11,24 @@ namespace umbraco.presentation.install
protected void Page_Load(object sender, System.EventArgs e)
{
var result = ApplicationContext.Current.DatabaseContext.ValidateDatabaseSchema();
var determinedVersion = result.DetermineInstalledVersion();
// Display the Umbraco upgrade message if Umbraco is already installed
if (String.IsNullOrWhiteSpace(GlobalSettings.ConfigurationStatus) == false)
if (String.IsNullOrWhiteSpace(GlobalSettings.ConfigurationStatus) == false || determinedVersion.Equals(new Version(0, 0, 0)) == false)
{
ph_install.Visible = false;
ph_upgrade.Visible = true;
}
// Check for config!
if (GlobalSettings.Configured)
{
Application.Lock();
Application["umbracoNeedConfiguration"] = null;
Application.UnLock();
Response.Redirect(Request.QueryString["url"] ?? "/", true);
}
// Check for config!
if (GlobalSettings.Configured)
{
Application.Lock();
Application["umbracoNeedConfiguration"] = null;
Application.UnLock();
Response.Redirect(Request.QueryString["url"] ?? "/", true);
}
}
protected void gotoNextStep(object sender, EventArgs e) {