Fixed modelstate persistence on import screen in case of validation errors.

This commit is contained in:
Sipke Schoorstra
2015-07-16 14:58:57 +01:00
parent 262454322c
commit 5aecec3127
5 changed files with 43 additions and 25 deletions

View File

@@ -24,11 +24,11 @@ namespace Orchard.ImportExport.Providers.ImportActions {
private readonly IEnumerable<IRecipeExecutionStep> _recipeExecutionSteps; private readonly IEnumerable<IRecipeExecutionStep> _recipeExecutionSteps;
public UploadRecipeAction( public UploadRecipeAction(
IOrchardServices orchardServices, IOrchardServices orchardServices,
IImportExportService importExportService, IImportExportService importExportService,
ISetupService setupService, ISetupService setupService,
ShellSettings shellSettings, ShellSettings shellSettings,
IFeatureManager featureManager, IFeatureManager featureManager,
IEnumerable<IRecipeExecutionStep> recipeExecutionSteps) { IEnumerable<IRecipeExecutionStep> recipeExecutionSteps) {
_orchardServices = orchardServices; _orchardServices = orchardServices;
@@ -86,6 +86,17 @@ namespace Orchard.ImportExport.Providers.ImportActions {
} }
} }
var stepUpdater = new Updater(updater, secondHalf => String.Format("{0}.{1}", Prefix, secondHalf));
// Update the view model with non-submitted values.
viewModel.SuperUserName = _orchardServices.WorkContext.CurrentSite.SuperUser;
foreach (var stepViewModel in viewModel.RecipeExecutionSteps) {
var step = _recipeExecutionSteps.Single(x => x.Name == stepViewModel.Name);
stepViewModel.DisplayName = step.DisplayName;
stepViewModel.Description = step.Description;
stepViewModel.Editor = step.UpdateEditor(shapeFactory, stepUpdater);
}
if (!isInValid) { if (!isInValid) {
// Read recipe file. // Read recipe file.
RecipeDocument = XDocument.Parse(new StreamReader(file.InputStream).ReadToEnd()); RecipeDocument = XDocument.Parse(new StreamReader(file.InputStream).ReadToEnd());
@@ -93,20 +104,19 @@ namespace Orchard.ImportExport.Providers.ImportActions {
// Update execution steps. // Update execution steps.
var executionStepNames = viewModel.RecipeExecutionSteps.Where(x => x.IsSelected).Select(x => x.Name); var executionStepNames = viewModel.RecipeExecutionSteps.Where(x => x.IsSelected).Select(x => x.Name);
var executionStepsQuery = var executionStepsQuery =
from name in executionStepNames from name in executionStepNames
where orchardElement.Element(name) != null where orchardElement.Element(name) != null
let provider = _recipeExecutionSteps.SingleOrDefault(x => x.Name == name) let provider = _recipeExecutionSteps.SingleOrDefault(x => x.Name == name)
where provider != null where provider != null
select provider; select provider;
var executionSteps = executionStepsQuery.ToArray(); var executionSteps = executionStepsQuery.ToArray();
var stepUpdater = new Updater(updater, secondHalf => String.Format("{0}.{1}", Prefix, secondHalf));
foreach (var executionStep in executionSteps) { foreach (var executionStep in executionSteps) {
var context = new UpdateRecipeExecutionStepContext { var context = new UpdateRecipeExecutionStepContext {
RecipeDocument = RecipeDocument, RecipeDocument = RecipeDocument,
Step = orchardElement.Element(executionStep.Name) Step = orchardElement.Element(executionStep.Name)
}; };
executionStep.UpdateEditor(shapeFactory, stepUpdater, context); executionStep.UpdateStep(context);
} }
} }
} }

View File

@@ -11,12 +11,13 @@
<input type="file" id="RecipeFile" size="64" name="RecipeFile" value="@T("Browse...")"/> <input type="file" id="RecipeFile" size="64" name="RecipeFile" value="@T("Browse...")"/>
</fieldset> </fieldset>
<fieldset> <fieldset>
<div> <legend>
@Html.CheckBoxFor(m => m.ResetSite) @Html.CheckBoxFor(m => m.ResetSite)
@Html.LabelFor(m => m.ResetSite, T("Reset Site").ToString(), new {@class = "forcheckbox"}) @Html.LabelFor(m => m.ResetSite, T("Reset Site").ToString(), new {@class = "forcheckbox"})
@Html.Hint(T("Check this option to reset your site before executing the uploaded recipe.")) </legend>
</div> @Html.Hint(T("Check this option to reset your site before executing the uploaded recipe."))
<div data-controllerid="@Html.FieldIdFor(m => m.ResetSite)"> <div data-controllerid="@Html.FieldIdFor(m => m.ResetSite)">
<div class="message message-Warning">@T("This will delete your database tables. Please consider creating a backup first.")</div>
<div> <div>
@Html.LabelFor(m => m.SuperUserPassword, T("Super User Password")) @Html.LabelFor(m => m.SuperUserPassword, T("Super User Password"))
@Html.PasswordFor(m => m.SuperUserPassword, new {@class = "text medium"}) @Html.PasswordFor(m => m.SuperUserPassword, new {@class = "text medium"})
@@ -27,19 +28,19 @@
@Html.PasswordFor(m => m.SuperUserPasswordConfirmation, new {@class = "text medium"}) @Html.PasswordFor(m => m.SuperUserPasswordConfirmation, new {@class = "text medium"})
@Html.Hint(T("Repeat the password to make sure you didn't mistype anything.")) @Html.Hint(T("Repeat the password to make sure you didn't mistype anything."))
</div> </div>
<div class="message message-Warning">@T("This will delete your database tables. Please consider creating a backup first.")</div>
</div> </div>
</fieldset> </fieldset>
@{ @{
var stepIndex = 0; var stepIndex = 0;
foreach (var step in Model.RecipeExecutionSteps) { foreach (var step in Model.RecipeExecutionSteps) {
var stepName = Html.NameFor(m => m.RecipeExecutionSteps[stepIndex].IsSelected).ToString(); var stepId = Html.FieldIdFor(m => m.RecipeExecutionSteps[stepIndex].IsSelected);
var stepId = stepName.HtmlClassify(); if (stepIndex <= Model.RecipeExecutionSteps.Count) {
<hr />
}
<fieldset class="recipe-builder-step recipe-builder-step-@step.Name.HtmlClassify()"> <fieldset class="recipe-builder-step recipe-builder-step-@step.Name.HtmlClassify()">
<legend> <legend>
<input type="hidden" name="@Html.NameFor(m => m.RecipeExecutionSteps[stepIndex].Name)" value="@Model.RecipeExecutionSteps[stepIndex].Name" /> <input type="hidden" name="@Html.FieldNameFor(m => m.RecipeExecutionSteps[stepIndex].Name)" value="@Model.RecipeExecutionSteps[stepIndex].Name" />
<input type="checkbox" id="@stepId" name="@stepName" value="true" /> @Html.CheckBoxFor(m => m.RecipeExecutionSteps[stepIndex].IsSelected)
<label for="@stepId" class="forcheckbox">@step.DisplayName</label> <label for="@stepId" class="forcheckbox">@step.DisplayName</label>
</legend> </legend>
@Html.Hint(step.Description) @Html.Hint(step.Description)
@@ -48,8 +49,5 @@
</div> </div>
</fieldset> </fieldset>
stepIndex++; stepIndex++;
if (stepIndex < Model.RecipeExecutionSteps.Count) {
<hr />
}
} }
} }

View File

@@ -33,22 +33,28 @@ namespace Orchard.Recipes.Providers.Executors {
get { return T("Provides additional coniguration for the Content recipe step."); } get { return T("Provides additional coniguration for the Content recipe step."); }
} }
public int? BatchSize { get; set; }
public override dynamic BuildEditor(dynamic shapeFactory) { public override dynamic BuildEditor(dynamic shapeFactory) {
return UpdateEditor(shapeFactory, null, null); return UpdateEditor(shapeFactory, null);
} }
public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater, UpdateRecipeExecutionStepContext context) { public override dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
var viewModel = new ContentExecutionStepViewModel(); var viewModel = new ContentExecutionStepViewModel();
if (updater != null) { if (updater != null) {
if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { if (updater.TryUpdateModel(viewModel, Prefix, null, null)) {
SetBatchSizeForDataStep(context.Step, viewModel.BatchSize); BatchSize = viewModel.BatchSize;
} }
} }
return shapeFactory.EditorTemplate(TemplateName: "ExecutionSteps/Content", Model: viewModel, Prefix: Prefix); return shapeFactory.EditorTemplate(TemplateName: "ExecutionSteps/Content", Model: viewModel, Prefix: Prefix);
} }
public override void UpdateStep(UpdateRecipeExecutionStepContext context) {
SetBatchSizeForDataStep(context.Step, BatchSize);
}
// <Data /> // <Data />
// Import Data. // Import Data.
public override void Execute(RecipeExecutionContext context) { public override void Execute(RecipeExecutionContext context) {

View File

@@ -8,7 +8,8 @@ namespace Orchard.Recipes.Services {
LocalizedString DisplayName { get; } LocalizedString DisplayName { get; }
LocalizedString Description { get; } LocalizedString Description { get; }
dynamic BuildEditor(dynamic shapeFactory); dynamic BuildEditor(dynamic shapeFactory);
dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater, UpdateRecipeExecutionStepContext context); dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater);
void UpdateStep(UpdateRecipeExecutionStepContext context);
void Execute(RecipeExecutionContext context); void Execute(RecipeExecutionContext context);
} }

View File

@@ -22,10 +22,13 @@ namespace Orchard.Recipes.Services {
return null; return null;
} }
public virtual dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater, UpdateRecipeExecutionStepContext context) { public virtual dynamic UpdateEditor(dynamic shapeFactory, IUpdateModel updater) {
return null; return null;
} }
public virtual void UpdateStep(UpdateRecipeExecutionStepContext context) {
}
public abstract void Execute(RecipeExecutionContext context); public abstract void Execute(RecipeExecutionContext context);
} }
} }