I am writing a registration page that has both options to register and log in. I would like for these views and models to remain separate, so I am using partial views. However, I am getting a null reference exception when the second partial view attempts to initialize its model. Help would be appreciated.
The null reference exceptions occurs at
#Html.Partial("Login",Model.Login)
RegisterModel
public class RegisterModel
{
public LoginModel Login { get; set; }
public RegisterModel()
{
Login = new LoginModel();
}
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
LoginModel
public class LoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
Login.cshtml
#model MvcApplication1.Models.LoginModel
#{
ViewBag.Title = "Log in";
}
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
</hgroup>
<section id="loginForm">
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
#Html.LabelFor(m => m.UserName)
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
#Html.LabelFor(m => m.Password)
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</li>
<li>
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe, new { #class = "checkbox" })
</li>
</ol>
<input type="submit" value="Log in" />
</fieldset>
}
</section>
#*<section class="social" id="socialLoginForm">
<h2>Use another service to log in.</h2>
#Html.Action("ExternalLoginsList", new { ReturnUrl = ViewBag.ReturnUrl })
</section>*#
And Register.cshtml (the index)
#model MvcApplication1.Models.RegisterModel
#{
ViewBag.Title = "stuff";
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<div class="register">
<div class="registration_contents">
#Html.Partial("RegisterForm")
</div>
<div class="login_contents">
#Html.Partial("Login",Model.Login)
</div>
</div>
</div>
</section>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Good afternoon, it looks like in your get request for the Register view you are more than likely not directly instantiating your RegisterModel so when you pass Model.Login to your partial call it is null.
Related
How do you add the option to upload a profile image to the default RegisterModel in MVC 4?
This answer converts the image to a byte array so that you can then save it in a database. It can easily be modified if you wanted to save the image to file store.
The code for the View Model. The important part is the multipart/form-data attribute:
#using (Html.BeginForm("Register", "Account", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<fieldset>
<legend>Registration Form</legend>
<ol>
<li>
#Html.LabelFor(m => m.UserName)
#Html.TextBoxFor(m => m.UserName)
</li>
<li>
#Html.LabelFor(m => m.Password)
#Html.PasswordFor(m => m.Password)
</li>
<li>
#Html.LabelFor(m => m.ConfirmPassword)
#Html.PasswordFor(m => m.ConfirmPassword)
</li>
<li>
<label for="register-avatar">Upload your photo</label>
<input id="register-avatar" type="file" name="ProfileImage" />
</li>
</ol>
<input type="submit" value="Register" />
</fieldset>
}
The RegisterModel:
public class RegisterModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public HttpPostedFileBase ProfileImage { get; set; }
}
The AccountController's HTTPPost for the Register.cshtml View:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
MemoryStream target = new MemoryStream();
model.ProfileImage.InputStream.CopyTo(target);
byte[] data = target.ToArray();
var profileImage = new ProfileImage();
profileImage.Data = data;
profileImage.MimeType = model.ProfileImage.ContentType;
/// other code to save the image to the database
return RedirectToAction("Index", "Profile/" + model.UserName);
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
This is a quick run down of how I managed to upload a profile image along with the registration built into the MVC 4 template.
I'm using .net 4.0 so can't utilize the built in FileExtensions attribute.
I'm trying to roll up my own validation but running into a stumbling block. I found this article which looks to be a good resource: http://blog.tomasjansson.com/creating-custom-unobtrusive-file-extension-validation-in-asp-net-mvc-3-and-jquery
but alas, my object (value) is always coming in as null. the only thing I'm doing differently is I'm not using the HttpPostedFileBase as my model, I'm using my viewmodel which has a few other properties.
any ideas how I can populate my object in the IsValid overload so that I can check it?
Here is my code which is more or less a copy and paste from that article with the exception that I've got more in my viewmodel:
ViewModel:
public class Mp3ViewModel
{
public string FileName { get; set; }
public string FilePath { get; set; }
[Required(ErrorMessage="You must enter a description of the MP3")]
[Display(Name = "Description of MP3:")]
public string Description { get; set; }
[Required(ErrorMessage = "You must enter a job role")]
[Display(Name = "Job Role:")]
public string CallJobRole { get; set; }
[Required(ErrorMessage = "You must enter a call outcome")]
[Display(Name = "Call Outcome:")]
public string CallOutcome { get; set; }
[Required(ErrorMessage = "You must enter a call type")]
[Display(Name = "Call Type:")]
public string CallType { get; set; }
[Required(ErrorMessage = "You must enter a call section")]
[Display(Name = "Call Section:")]
public string CallSection { get; set; }
[Required(ErrorMessage = "You must enter call comments")]
[Display(Name = "Call Comments:")]
public string CallComments { get; set; }
[Required(ErrorMessage = "You must enter call keywords")]
[Display(Name = "Call Keywords (separate by comma):")]
public string CallKeywords { get; set; }
[Required(ErrorMessage = "You must select a file")]
[Display(Name = "Select an MP3 to upload:")]
[FileExtensions("txt|doc")]
public HttpPostedFileBase Mp3 { get; set; }
}
Custom Attribute Validation:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FileExtensionsAttribute : ValidationAttribute
{
private List<string> ValidExtensions { get; set; }
public FileExtensionsAttribute(string fileExtensions)
{
ValidExtensions = fileExtensions.Split('|').ToList();
}
public override bool IsValid(object value)
{
HttpPostedFileBase file = value as HttpPostedFileBase;
if (file != null)
{
var fileName = file.FileName;
var isValidExtension = ValidExtensions.Any(y => fileName.EndsWith(y));
return isValidExtension;
}
return true;
}
}
View:
#model CallLibrary.BO.ViewModels.Mp3ViewModel
#{
ViewBag.Title = "Call Library Administration";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section scripts
{
<script src="~/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
}
<h2>Call Library Administration</h2>
#ViewBag.test
#using (Html.BeginForm())
{
<div>
#Html.ValidationMessageFor(x => x.Description)<br />
#Html.LabelFor(x => x.Description)
#Html.TextAreaFor(x => x.Description)
</div>
<div>
#Html.ValidationMessageFor(x => x.CallJobRole)<br />
#Html.LabelFor(x => x.CallJobRole)
#Html.TextBoxFor(x => x.CallJobRole)
</div>
<div>
#Html.ValidationMessageFor(x => x.CallOutcome)<br />
#Html.LabelFor(x => x.CallOutcome)
#Html.TextBoxFor(x => x.CallOutcome)
</div>
<div>
#Html.ValidationMessageFor(x => x.CallType)<br />
#Html.LabelFor(x => x.CallType)
#Html.TextBoxFor(x => x.CallType)
</div>
<div>
#Html.ValidationMessageFor(x => x.CallSection)<br />
#Html.LabelFor(x => x.CallSection)
#Html.TextBoxFor(x => x.CallSection)
</div>
<div>
#Html.ValidationMessageFor(x => x.CallComments)<br />
#Html.LabelFor(x => x.CallComments)
#Html.TextAreaFor(x => x.CallComments)
</div>
<div>
#Html.ValidationMessageFor(x => x.CallKeywords)<br />
#Html.LabelFor(x => x.CallKeywords)
#Html.TextAreaFor(x => x.CallKeywords)
</div>
<div>
#Html.ValidationMessageFor(x=>x.Mp3)<br />
#Html.LabelFor(x=>x.Mp3)
#Html.TextBoxFor(x=>x.Mp3, new {type= "file"})
</div>
<div>
<input type="submit" value="Add MP3" />
</div>
}
any suggestions would be greatly appreciated.
TIA
doh! my bad. I wasn't using a form with multipart form data. when I added that, all is good in the world.
I have an Index page which has two partial views: login and register.I am using data model validation.
Login.cshtml
#model Project.ViewModel.UserModel
<div style="position:inherit;">
#using (Html.BeginForm("_Login", "account"))
{
#Html.ValidationSummary(true)
<div class="label">#Html.Label("Username")</div>
<div class="field">#Html.TextBoxFor(m => m.Username)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Username)</div>
<div class="label">#Html.Label("Password")</div>
<div class="field">#Html.PasswordFor(m => m.Password)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Password)</div>
<input class="field" id="submit" type="submit" value="Login" />
}
Register.cshtml
#model Project.ViewModel.UserModel
<link href="~/Content/Site.css" rel="stylesheet" />
<div style="position: inherit; margin-top: 20px">
#using (Html.BeginForm("_Register","account"))
{
<div class="label">#Html.Label("Name")</div>
<div class="field">#Html.TextBoxFor(m => m.FullName)</div>
<div class="error">#Html.ValidationMessageFor(model => model.FullName)</div>
<div class="label">#Html.Label("Username")</div>
<div class="field">#Html.TextBoxFor(m => m.Username)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Username)</div>
<div class="label">#Html.Label("Password")</div>
<div class="field">#Html.PasswordFor(m => m.Password)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Password)</div>
<div class="label">#Html.Label("Confirm Password")</div>
<div class="field">#Html.PasswordFor(m => m.ConfirmPassword)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Password)</div>
<div class="label">#Html.Label("Email")</div>
<div class="field">#Html.TextBoxFor(m => m.Email)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Email)</div>
<div class="label">#Html.Label("Country")</div>
<div class="field">#Html.TextBoxFor(m => m.Country)</div>
<div class="error">#Html.ValidationMessageFor(model => model.Email)</div>
<input class="field" id="submit" type="submit" value="Sign Up" />
#Html.ValidationSummary()
}
Index.cshtml
#model Project.ViewModel.UserModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="regiserandlogin">
<div id="registerandlogin-header">
<label style="margin-left:50px;">Sign Up For Free!!!</label>
<label style="margin-left:350px;color:#28a1e2">Already Have An Account?</label>
</div>
<div id="registerbox">
#Html.Partial("_Register", new ProjectHub.ViewModel.UserModel())
</div>
<div id="loginbox">
#Html.Partial("_Login", new ProjectHub.ViewModel.UserModel())
</div>
public ViewResult _Register()
{
return View("_Register");
}
[HttpPost]
public ActionResult _Register(UserModel usermodel)
{
if (!ModelState.IsValid)
{
return View("Index");
}
try
{
FormsAuthentication.SetAuthCookie(usermodel.Username, false);
return RedirectToAction("activationemail", new {username= Username});
}
catch (Exception ae)
{
ModelState.AddModelError("", ae.Message);
return View();
}
}
public ViewResult _Login()
{
return View("_Login");
}
[HttpPost]
public ActionResult _Login(string username, string password)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(username, password))
{
if (!repository.IsVerified(username))
{
ModelState.AddModelError("","Account is not activated.;
return View();
}
FormsAuthentication.SetAuthCookie(username,false);
return RedirectToAction("Index","Home");
}
return RedirectToAction("Index", "account"); ;
}
else
{
ModelState.AddModelError("","Invalid Username/Password");
return View();
}
}
UserModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace ProjectHub.ViewModel
{
public class UserModel
{
[Required(ErrorMessage="Username is Required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Name is Required")]
public string FullName { get; set; }
[Required(ErrorMessage = "Email is Required")]
public string Email { get; set; }
[Required(ErrorMessage = "Country is Required")]
public string Country { get; set; }
}
}
When I press register button like this, I get a validation error
If I use RedirectToAction Method, I don't get the validation error.
Please advise me.
You should not use the same view model for both partials. You should have 2 different view models.
For example:
public class LoginViewModel
{
[Required(ErrorMessage="Username is Required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
}
and for the register partial:
public class RegisterViewModel
{
[Required(ErrorMessage="Username is Required")]
public string Username { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string Password { get; set; }
[Required(ErrorMessage = "Password is Required")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "Name is Required")]
public string FullName { get; set; }
[Required(ErrorMessage = "Email is Required")]
public string Email { get; set; }
[Required(ErrorMessage = "Country is Required")]
public string Country { get; set; }
}
and then your main view model should aggregate those 2 view models:
public class MyViewModel
{
public LoginViewModel Login { get; set; }
public LoginViewModel Register { get; set; }
}
and then:
<div id="registerbox">
#Html.Partial("_Register", Model.Login)
</div>
<div id="loginbox">
#Html.Partial("_Login", Model.Register)
</div>
Add the following reference to the JQuery scripts in your View.
I went through the same situation and it solved my problem.
"~/Scripts/jquery.unobtrusive*"
"~/Scripts/jquery.validate*"
I have a simple Model that is the default RegisterModel and upon creating a View based on that model for Create I end up having
public class RegisterModel
{
[Required]
[Remote("UserNameExists", "Account", "", ErrorMessage = "Username is already taken.")]
[Display(Name = "Username (spaces will be stripped, must be at least 6 characters long)")]
public string UserName { get; set; }
[Required]
[Editable(true)]
[Display(Name = "First and Last name")]
public string Name { get; set; }
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "You need to enter a valid email")]
[Remote("EmailExists", "Account", "", ErrorMessage = "Email is already taken.")]
[Display(Name = "Email address")]
public string Email { get; set; }
//[Required]
//[ValidatePasswordLength]
[DataType(DataType.Password)]
[Display(Name = "Create a password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Verify password")]
//[Compare("Password", ErrorMessage = "Password's do not match.")]
public string ConfirmPassword { get; set; }
}
and in the View:
<h3>
Details</h3>
#using (Html.BeginForm("GenerateBetaLink", "Account", FormMethod.Post, new { #id = "beta-user" }))
{
#Html.ValidationSummary(true)
<div>
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
</div>
<p>
</p>
<p>
<input type="submit" value="Create Beta User" class="btn-submit" />
<span class="loading"></span>
</p>
</div>
}
My Validation Controller
public class ValidationController : Controller
{
public JsonResult UserNameExists(string UserName)
{
OnlineServicesRepository db = new OnlineServicesRepository();
var user = db.FindUserByUsername(UserName.Trim());
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", UserName),
JsonRequestBehavior.AllowGet);
}
public JsonResult EmailExists(string Email)
{
OnlineServicesRepository db = new OnlineServicesRepository();
var user = db.FindUserByEmail(Email.Trim());
return user != null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", Email),
JsonRequestBehavior.AllowGet);
}
}
My problem is that Remote Validation does fire, but does not write anything into the Error Message as it should, plus, the jQuery method .valid() keeps telling me that the form is valid:
(source: balexandre.com)
What am I missing here?
The MSDN article shows the same code (in the downloadable file)
The following worked fine for me:
Model:
public class RegisterModel
{
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "You need to enter a valid email")]
[Remote("EmailExists", "Home", "")]
[Display(Name = "Email address")]
public string Email { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(RegisterModel model)
{
return View(model);
}
public ActionResult EmailExists(string email)
{
if ((email ?? string.Empty).Contains("foo"))
{
return Json(email + " is not available", JsonRequestBehavior.AllowGet);
}
return Json(true, JsonRequestBehavior.AllowGet);
}
}
View:
#model RegisterModel
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.LabelFor(model => model.Email)
#Html.EditorFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
<input type="submit" value="OK" />
}
I had the same problem and resolved it by updating to the latest jQuery (1.6) and jQuery.validate (1.8) libraries. The easiest way to get these is searching NuGet for jQuery.
How can i make this work like I have 5 fields in my database table .
I created a model for validation with datannotations and created the compare password field as well with comparepassword attribute. (now my model has 6 fields including one external field compare password and 5 database fields)
I created a view with that model.(User)
Now I created a controller as well but the problem arise here that when calling that ActionMethod the compiler complains about the external field and tells it cannot find any extension method. How can I create the extension method or solve this error?
[HttpPost]
public ActionResult Create(User Users)
{
}
This is the error I get:
CS1061: 'MvcApplication1.Models.User' does not contain a definition for 'ComparePassword' and no extension method 'ComparePassword' accepting a first argument of type 'MvcApplication1.Models.User' could be found (are you missing a using directive or an assembly reference?)
My Model:
[MetadataType(typeof(UserModel))]
public partial class User { }
public class UserModel
{
[Display(Name = "User Name")]
[Remote("Username", "User", ErrorMessage = "User Name already exists")]
[Required(ErrorMessage = "User Name is required")]
public string vcr_UserName { get; set; }
[RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Must be a valid Email Address")]
[Remote("EmailAddress", "User", ErrorMessage = "Email Address already exists")]
[Required(ErrorMessage = "Email is required")]
[Display(Name = "Email Address")]
public string vcr_EmailAddress { get; set; }
[Display(Name = "Password")]
[RegularExpression(#"^.{3,16}$", ErrorMessage = "The Password length must be between 3 and 16 characters ")]
[Required(ErrorMessage = "Password is required")]
public string vcr_Password { get; set; }
[Display(Name = "Compare Password")]
[Compare("vcr_Password", ErrorMessage = "Passwords do not match")]
public string ComparePassword { get; set; }
[Required(ErrorMessage = "Country is required")]
[Display(Name = "Country")]
public string vcr_Country { get; set; }
[Required(ErrorMessage = "Website is required")]
[Display(Name = "WebSite")]
public string vcr_Website { get; set; }
[Display(Name = "Expertise")]
[Required(ErrorMessage = "Expertise is required")]
public string vcr_Expertise { get; set; }
public int int_GroupId { get; set; }
public Boolean bit_Active { get; set; }
}
My Controller
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(User Users)
{
try
{
UserRepository UserRep = new UserRepository();
if (ModelState.IsValid)
{
Users.int_GroupId = 2;
Users.dtm_CreatedDate = DateTime.Now;
Users.bit_Active = true;
UserRep.Add(Users);
UserRep.Save();
}
return View();
}
catch { return View(); }
}
View
#model MvcApplication1.Models.User
{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
Index
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Users</legend>
<div class="editor-label">
#Html.LabelFor(model => model.vcr_UserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.vcr_UserName)
#Html.ValidationMessageFor(model => model.vcr_UserName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.vcr_Password)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.vcr_Password)
#Html.ValidationMessageFor(model => model.vcr_Password)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ComparePassword)
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.ComparePassword)
#Html.ValidationMessageFor(model => model.ComparePassword)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.vcr_EmailAddress)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.vcr_EmailAddress)
#Html.ValidationMessageFor(model => model.vcr_EmailAddress)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Ok when i click the create i am getting the above error
What do you mean by "external field"?
One thing that already comes to mind is:
Data annotations for view behaviour should not be placed on a model class.
You should separate your model facing the database from the viewmodel facing the view.
There are numerous articles about that.
If you create a viewmodel, you can add the 6th field there, add the data annotations, have the validation do its thing, etc.
You can use a tool like AutoMapper or ValueInjecter to perform the mapping from model to viewmodel and vice versa, so you don't have to write too much code.
If you have any further questions, feel free to ask...