I have a user object:
namespace MySolution.Models
{
public class MyUser
{
public Int32 Id { get; set; }
[Required]
public string CompanyName { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
}
}
Id is auto generated by SQL Server. I am using Dapper.
All these properties are required. However I want to split this into two parts - so the user is asked first for Email - then on the next 'page' for Company name, first name & last name.
The [HttpPost] controllers looks like this:
[HttpPost]
public ActionResult SignUp(MyUser myuser)
{
if (ModelState.IsValid)
{
// Insert returns success
if (MyUserRepo.InsertEmailPass(myuser))
{
// Successfully added user, go to next user section
return RedirectToAction("SignUp2", myuser);
}
else
{
// Adding prospect failed
ViewBag.Error = "Email already registered";
}
}
return View(myuser);
}
[HttpPost]
public ActionResult SignUp2(MyUser myuser)
{
if (ModelState.IsValid)
{
// Insert returns success
if (MyUserRepo.UpdateNameCopany(myuser))
{
// Successfully added myuser, go to thank you page
return RedirectToAction("SignUpEnd");
}
else
{
// Adding prospect failed
ViewBag.Error = "Something went wrong";
}
}
}
I want unobtrusive validation and all the built in MVC capabilities - such as if (ModelState.IsValid)
- however, as I'm splitting this over 2 pages the model will never be valid on the first page - and unless I manually add email to the model on the second page there too (whereas all I need to do is a SQL update on first name, last name & company name (not email)- so adding email to the SQL un-necessarily).
This all feels rather 'hacky'. How can I do this and still use built in validation and ModelState etc?
I can find nothing about this on Google.
My aim is to do this 'correctly', with minimal code, in a clear way (& best practice?).
EDIT: I now have these 2 view models:
namespace MyNamespace.ViewModels
{
public class SignUpViewModelPage1
{
public int Id { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[StringLength(50, MinimumLength = 8, ErrorMessage = "{0} must be at least {2} characters long")]
[DataType(DataType.Password)]
public string Password { get; set; }
}
public class SignUpViewModelPage2
{
public int Id { get; set; }
[Required]
public string CompanyName { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
}
}
The controllers:
[HttpPost]
public ActionResult SignUp(SignUpViewModelPage1 svmp1)
{
if (ModelState.IsValid)
{
int Id = senderRepo.InsertEmailPass(svmp1);
// Insert failure returns -1
if (Id != -1)
{
// Successfully added user - go to page 2, pass Id
return RedirectToAction("SignUp2", new { Id = Id });
}
else
{
// Adding user failed - probably duplicate email - tell user & pass invalid model back
ViewBag.Error = "Email already registered";
}
}
return View(svmp1);
}
public ActionResult SignUp2(int Id)
{
return View();
}
[HttpPost]
public ActionResult SignUp2(SignUpViewModelPage2 svmp2)
{
if (ModelState.IsValid)
{
// Insert success returns true
if (senderRepo.UpdateNameCopany(svmp2))
{
// Successfully added user - go to success page
return RedirectToAction("SignUpEnd");
}
else
{
// Adding user failed - tell user
ViewBag.Error = "Email already registered";
}
}
return View();
}
Does this all look OK? Any obvious errors or bad ways of doing things?
thx