Created
October 2, 2013 14:12
-
-
Save robdmoore/6794397 to your computer and use it in GitHub Desktop.
Multi-step form controller code idea
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel.DataAnnotations; | |
using System.IO; | |
using System.Linq; | |
using System.Web.Mvc; | |
using Newtonsoft.Json; | |
namespace Web.Controllers | |
{ | |
public class RegistrationController : Controller | |
{ | |
private const string SerialisedValuesKey = "SerialisedValues"; | |
private const string ValidationHashKey = "ValidationHash"; | |
private const string SecretSalt = "drthSRT$%^7#fgh;awGSEER"; | |
private static readonly LinkedList<RegistrationFormSteps> FormSteps = new LinkedList<RegistrationFormSteps>(Enums.Enumerate<RegistrationFormSteps>()); | |
// This isn't used below, but it contains some logic around what might be done for the hidden field tracking. | |
private TReturn SaveFormStateAndReturn<TReturn>(Action<RegistrationFormViewModel> modifier, Func<RegistrationFormViewModel, TReturn> returnAccessor) | |
{ | |
var vm = new RegistrationFormViewModel(); | |
var serialised = Request.Params[SerialisedValuesKey]; | |
if (!string.IsNullOrEmpty(serialised)) | |
{ | |
var expectedHash = (serialised + SecretSalt).ToSha1Hash(); | |
var hash = Request.Params[ValidationHashKey]; | |
if (hash != expectedHash) | |
throw new InvalidDataException("User tampered with registration submission"); | |
vm = JsonConvert.DeserializeObject<RegistrationFormViewModel>(serialised); | |
} | |
modifier(vm); | |
ViewData[SerialisedValuesKey] = JsonConvert.SerializeObject(vm); | |
ViewData[ValidationHashKey] = (ViewData[SerialisedValuesKey] + SecretSalt).ToSha1Hash(); | |
return returnAccessor(vm); | |
} | |
public ActionResult Step1() | |
{ | |
return View(); | |
} | |
[HttpPost] | |
public ActionResult Step1(Step1ViewModel vm) | |
{ | |
return FormStep(RegistrationFormSteps.Step1); | |
} | |
[HttpPost] | |
public ActionResult Step2(Step2ViewModel vm) | |
{ | |
return FormStep(RegistrationFormSteps.Step2); | |
} | |
private ActionResult FormStep(RegistrationFormSteps currentStep) | |
{ | |
if (!ModelState.IsValid) | |
return View(currentStep.ToString(), GetViewModel(currentStep)); | |
SaveFormState(currentStep); | |
var stepToShow = default(RegistrationFormSteps?); | |
if (currentStep != FormSteps.First() && Request.Params["previous"] != null) | |
stepToShow = GetPreviousStep(currentStep); | |
if (currentStep != FormSteps.Last() && (Request.Params["next"] != null)) | |
stepToShow = GetNextStep(currentStep); | |
if (!stepToShow.HasValue && currentStep == FormSteps.Last()) | |
return ProcessRegistration(); | |
return View(stepToShow.ToString(), GetViewModel(stepToShow)); | |
} | |
} | |
public enum RegistrationFormSteps | |
{ | |
Step1, | |
Step2 | |
} | |
public class RegistrationFormViewModel | |
{ | |
public Step1ViewModel Step1 { get; set; } | |
public Step2ViewModel Step2 { get; set; } | |
} | |
public class Step1ViewModel | |
{ | |
[Required] | |
public string FirstName { get; set; } | |
[Required] | |
public string LastName { get; set; } | |
} | |
public class Step2ViewModel | |
{ | |
[Required] | |
public string EmailAddress { get; set; } | |
[Required] | |
public string Address { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment