Search code examples
asp.net-mvc-4passwordsauto-populate

asp.net-mvc: Adding a passwordFor to the view auto populates my fields


The scenario: I am trying to add a view to Create new users by admin. The app is form authentication. There is a logged in user(admin). When a Password For is added to the view, the view automatically populates the fields with the logged in user.

The controller code:

public ActionResult Create()
{
    var userViewModel = new UserViewModel();
    return View(userViewModel);
}

The view code:

@model MVC4.Models.UserViewModel

@{
    ViewBag.Title = "Create";
}

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
    <legend>UserVireModelcs</legend>

    <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.Password)
    </div>
    <div class="editor-field">
        @Html.PasswordFor(model => model.Password)
        @Html.ValidationMessageFor(model => model.Password)
    </div>

    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>
}

Solution

  • What I suspect is happening here is that the application isn't pre-filling the fields, but the browser is. This is because this form looks exactly like a login prompt. (You can test this by clearing your information from the browser itself so that it doesn't auto-fill any login prompt on this site.)

    What I would recommend is to semantically separate the concepts of logging in and creating a user. Basically... rename the fields. A simple view model with some more specific names would help:

    public class CreateUserViewModel
    {
        public string NewUserUsername { get; set; }
        public string NewUserPasswords { get; set; }
    }
    

    Then use that in your view:

    <div class="editor-label">
        @Html.LabelFor(model => model. NewUserUsername)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model. NewUserUsername)
        @Html.ValidationMessageFor(model => model. NewUserUsername)
    </div>
    
    <div class="editor-label">
        @Html.LabelFor(model => model.NewUserPassword)
    </div>
    <div class="editor-field">
        @Html.PasswordFor(model => model.NewUserPassword)
        @Html.ValidationMessageFor(model => model.NewUserPassword)
    </div>
    

    It's a little more verbose than perhaps one might want it to be (I would agree that simpler is always better), but adding some explicit context to the naming in this case makes it more clear to the browser that this isn't a login form. Use any naming that makes sense for your needs, just make it more descriptive than Username and Password.