I have a MVC app which has the default login functionality and when I login with out checking the Remember me The check box model state gets added an error saying:
"The Remember me? field is required." with RememberMe key, its not marked required in Model class. For me Remember me is optional.
So when I check if(ModelState.IsValid) before validating the user, the IsValid property is false because of the RememberMe error.
So currently I'm removing this error with ModelState["RememberMe"].Errors.Clear(); in Login Action method and check ModelState.IsValid.
Is there a better way to avoid this error getting added to the ModelState?
I'm using VS 2012 RC
Controller
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl) {
ModelState["RememberMe"].Errors.Clear();
if(ModelState.IsValid) {
if(Membership.ValidateUser(model.UserName, model.Password)) {
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if(Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) {
return Redirect(returnUrl);
}
else {
return RedirectToAction("Index", "Home");
}
}
else {
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Model
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; }
}
View
@{ Layout = "~/Views/Shared/_lightLayout.cshtml"; }
@model MvcFoodService.Models.LoginModel
<div class="accountHeader">
<h2>
Log In</h2>
<p>
Please enter your username and password. @Html.ActionLink("Register", "Register")
if you don't have an account.</p>
</div>
@using(Html.BeginForm()) {
@Html.DevExpress().Label(settings => {
settings.Name = "UserNameLabel";
settings.Text = "User Name";
settings.AssociatedControlName = "UserName";
}).GetHtml()
<div class="form-field">
@Html.EditorFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</div>
@Html.DevExpress().Label(settings => {
settings.Name = "PasswordLabel";
settings.Text = "Password";
settings.AssociatedControlName = "Password";
}).GetHtml()
<div class="form-field">
@Html.EditorFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</div>
<div class="form-field">
@Html.DevExpress().CheckBox(settings => {
settings.Name = "RememberMe";
settings.Text = "Remember me?";
}).GetHtml()
</div>
@Html.DevExpress().Button(settings => {
settings.Name = "Button";
settings.Text = "Log On";
settings.UseSubmitBehavior = true;
}).GetHtml()
}
The RememberMe field is a checkbox. That means that it's not supplied in the post if unchecked.
So if you have like this in the action:
[HttpPost]
public ActionResult Login(string userName, string password, bool rememberMe)
{
}
it will fail, since no value is supplied.
You can solve it by modifying the action:
[HttpPost]
public ActionResult Login(string userName, string password, bool rememberMe = false)
{
}
That tells MVC that it's optional.
It can also be solved by including a hidden input in the form:
<input type="hidden" name="rememberme" value="false" />
<input type="checkbox" name="rememberme" value="true" />
That would send two values for rememberme if checked (the last value will be used) or just the hidden value (false) if unchecked.
Update
Since you are using a view model you have to make the RememberMe field bool? or change so there is a hidden input above the checkbox input.
Update2:
Just change to this in the view:
<div class="form-field">
@Html.DevExpress().CheckBox(settings => {
settings.Name = "RememberMe";
settings.Text = "Remember me?";
}).GetHtml()
<input type="hidden" name="RemberMe" value="false" />
</div>
And you're all set.
Side note
The code that ASP.NET MVC3:s action helper generates look like this:
<input data-val="true" data-val-required="The Remember me? field is required." id="RememberMe" name="RememberMe" type="checkbox" value="true" />
<input name="RememberMe" type="hidden" value="false" />
So DevExpress doesn't follow the behavior of MVC3 (as it should since it's built for ASP.NET MVC)
The RememberMe field is a devexpress nullable checkbox. You must set default value
@Html.DevExpress().CheckBox(settings => {
settings.Name = "RememberMe";
settings.Text = "Remember me?";
settings.Checked = false;
}).GetHtml()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With