Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Remote validate email or check if email exists

I am trying to check if Email exists at registration so that there are no duplicate emails in the database. I am doing this with the MVC4 default Internet Application but i have added an Email field to the RegisterviewModel. I also noticed that, this is well done with UserName field but i have no idea how they did it. I tried to follow This blog below but no luck as there is no response when i click create. Tug Berk. When i use firebug i am getting Status: 302 Found when Json action excutes

This is what i have have:

UserProfile

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
}

RegisterViewModel

public class RegisterModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email")]
    [Remote("DoesUserEmailExist", "Account", HttpMethod = "POST", ErrorMessage = "Email address already exists. Please enter a different Email address.")]
    public string Email { 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")]
    [System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

Register Action

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            try //CreateUserAndAccount
            {
                WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { model.Email });
                WebSecurity.Login(model.UserName, model.Password);
                return RedirectToAction("Index", "Home");

            }
            catch (MembershipCreateUserException e)
            {
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

Json Action

[HttpPost]
    public JsonResult DoesUserEmailExist(string email)
    {

        var user = Membership.GetUserNameByEmail(email);

        return Json(user == null);
    }

Edit: Added Register View

     @model Soccer.Models.RegisterModel

     @{
     ViewBag.Title = "Register";
     }

     <hgroup class="title">
     <h1>@ViewBag.Title.</h1>
     <h2>Create a new account.</h2>
     </hgroup>

 @using (Html.BeginForm()) {
 @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.Email)
            @Html.TextBoxFor(m => m.Email)
        </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>
    </ol>
    <input type="submit" value="Register" />
</fieldset>
 }

 @section Scripts {
 @Scripts.Render("~/bundles/jqueryval")
 }

Is there something i shouldn't be doing or is there another simpler option i could take here?

like image 463
Komengem Avatar asked Jan 17 '13 03:01

Komengem


People also ask

Is it possible to check if an email address exists?

The best and most recommended ways to verify an email address without sending an email are: Email verifier tools: Use an email verification service to check if the given address is valid or not. Just google 'Email Verifier,' and many free and paid options will come up.

What is the best way to validate email?

Double opt-in is the best way to validate email addresses. If your customers sign up for your email list or newsletter, send them an email that requests them to validate by responding. Many people don't like this option, as it may reduce your overall opt-in rates, but we believe it is better to have good data.


2 Answers

For starter, i would like to say thanks to JOBG for intracting with me through this. What i showed in the question above should still work if you use Database First as it demands that you set Email column UNIQUE in the database, however to make it work with EF Code First i had to do the following to the register action, also note that with this solution, you don't need Remote Annotation in the model:

Register Action

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // Insert a new user into the database
            using (UsersContext db = new UsersContext())
            {
                UserProfile email = db.UserProfiles.FirstOrDefault(u => u.Email.ToLower() == model.Email.ToLower());
                try
                {
                    // Check if email already exists
                    if (email == null)
                    {
                        WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email });
                        WebSecurity.Login(model.UserName, model.Password);
                        return RedirectToAction("Index", "Home");
                    }
                    else
                    {
                        ModelState.AddModelError("Email", "Email address already exists. Please enter a different email address.");
                    }
                }
                catch (MembershipCreateUserException e)
                {

                    ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                }
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

Note: Take note that this action validates Email before UserName and that it requires that you take a trip to the database atleast once before you create your object.

like image 199
Komengem Avatar answered Oct 14 '22 11:10

Komengem


Hard to tell without the View code but my first suspect is js, make sure you have jQuery validation plug-in set in place, it should be firing the validation with .blur() event, inspect the page with firebug(or similar) and look for an ajax POST that hits DoesUserEmailExist when the field loses focus, if this is not happening then something is missing in client side as Remote attribute and the service DoesUserEmailExist looks ok.

Side Note: Make sure you have the UNIQUE constraint in the database for the email field, this is the only real way to make sure you have no duplicate emails, even with the DoesUserEmailExist verification, because of concurrency.

like image 27
JOBG Avatar answered Oct 14 '22 11:10

JOBG