2

If you create a new ASP.net MVC 4 Application in Visual Studio 2012 Express - and select the Internet Application Template - it creates an Account model for you to manage users.

Out of the box this lets users register & login with a unique username and password.

You can also change the username to something else - for example an email address.

However, it is quite common to require users to enter a unique username AND email.

How can I change the out of the box functionality to check for this? Client side checking, in addition to server side, is preferable.

I am using Code First - so don't want to manually change the database & SQL Server 2012 Express.

Thanks.

tereško
  • 58,060
  • 25
  • 98
  • 150
niico
  • 11,206
  • 23
  • 78
  • 161
  • The frustration of this is that it would be trivial to do it with web forms & SQL Server stored procedures. Apparently MVC is progress ;).... – niico Aug 28 '13 at 21:34

2 Answers2

3

If you are using an out of the box template, you don't have to worry about Username, WebSecurity will take care of making sure that its unique. As for Email, this is what i did in my Web Application currently working on.

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            using (EfDb db = new EfDb())
            {
                UserProfile userEmail = db.UserProfiles.FirstOrDefault(u => u.Email.ToLower() == model.Email.ToLower());
                try
                {
                    // Check if email already exists
                    if (userEmail == null)
                    {
                        var token = WebSecurity.CreateUserAndAccount(
                            model.UserName,
                            model.Password,
                                new
                                    {
                                        model.Email                                           
                                    },
                            true);
                        }
                    ModelState.AddModelError("", ErrorCodeToString(MembershipCreateStatus.DuplicateEmail));
                }
                catch (MembershipCreateUserException e)
                {
                    ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                }
            }
        }
        // If we got this far, something failed, redisplay form
        return View(model);
    }

As you can see, Database has nothing to do with validation here. C# code takes care of it. Just make sure that in your ViewModel you have this:

    [EmailAddress]
    [Required]
    [Display(Name = "Email")]
    public string Email { get; set; }

In the View

    <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.Email)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Email)
        @Html.ValidationMessageFor(model => model.Email)
    </div>
Komengem
  • 3,662
  • 7
  • 33
  • 57
  • That's really helpful thanks - I'm pretty new to MVC. The next obvious question - how can users Login with email & password? ;). Or better still Username OR Email - and password? – niico Apr 09 '13 at 06:02
  • this looks interesting: http://stackoverflow.com/questions/12404438/how-to-make-websecurity-login-to-login-using-username-or-email – niico Apr 09 '13 at 06:11
  • @user2254951 If you want your users to login with Email address, the easiest way is to have `Username` property with `[EmailAddress]` Annotation. That way, you don't need `Email` property. Leave naming as is. Also if this answer has solved your question, please accept it. – Komengem Apr 09 '13 at 06:42
  • @user2254951 or you could go about like in that link, but i have a few other ideas we could try. It will be better if you asked this in a different question, so we can try a few things. – Komengem Apr 09 '13 at 06:49
  • @Komengem: is the `ModelState.AddModelError("", ErrorCodeToString(MembershipCreateStatus.DuplicateEmail));` shouldn't be in `else {}` block? In your case it will running always - not matter if email is duplicated or not. – 1_bug Feb 20 '15 at 15:24
0

There is no way to do this "automatically", I don't think. In your Account controller, before inserting a new username (creating a new account) you'd have to check if the submitted new username already exists in the database and send appropriate error message to the view in case username is found in the database.

With some JavaScript/jQuery you could implement "client side" checking, which would actually submit the new username to the server in the background (ajax request), for checking and display an error, or proceed with submitting the rest of the form depending on the result.

Floremin
  • 3,969
  • 15
  • 20