Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC login error - The Remember me? field is required

enter image description hereI 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()
}
like image 923
Nirushan Ferdinand Chandran Avatar asked Dec 30 '25 06:12

Nirushan Ferdinand Chandran


2 Answers

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)

like image 53
jgauffin Avatar answered Dec 31 '25 20:12

jgauffin


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()
like image 42
Gurgen Sargsyan Avatar answered Dec 31 '25 21:12

Gurgen Sargsyan