Question

I am building an MVC 4 application starting with the default internet application. My goal is to send a confirmation email to users as they register to the website, i have managed to send the confirmation email but when i click on it the account is not being confirmed.

Note: I know the Register action is crowded, i will separate pieces to different files when i make it work.

*This is what i have done:*

Register Action

[HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            try //CreateUserAndAccount
            {
                var token = WebSecurity.CreateUserAndAccount(model.UserName, model.Password, null, true);
                if (token != null)
                {
                    var hosturl =
                        System.Web.HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) +
                        "/Account/ConfirmAccount?token=" + token;

                    var confirmationLink = string.Format("<a href=\"{0}\">Clink to confirm your registration</a>",
                                                         hosturl);




                    var message = new MailMessage("komengem@gmail.com", model.UserName)
                    {
                        Subject = "Please confirm your email",
                        Body = confirmationLink
                    };

                    var client = new SmtpClient();
                    client.EnableSsl = true;
                    client.Send(message);
                }

                TempData["message"] = string.Format(
                    "Thank you for registering. An email has been sent to {0}. " +
                    "Please check your email and use the enclosed link to finish registration.", model.UserName);
                return RedirectToAction("Index", "Home");
            }
            catch (MembershipCreateUserException e)
            {
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
            }
        }

ConfirmAcount Action

public ActionResult ConfirmAccount(string ID)
    {
        //return View("ConfirmAccount");
        var confirmationToken = Request["token"];
        if (!String.IsNullOrEmpty(confirmationToken))
        {
            var user = WebSecurity.CurrentUserName;
            WebSecurity.ConfirmAccount(confirmationToken);
            WebSecurity.Login(user, null);
            return View("Welcome");
        }

        TempData["message"] = string.Format(
                    "Your account was not confirmed, please try again or contact the website adminstrator.");
        return RedirectToAction("Index", "Home");            
    }

Also Tried

public ActionResult ConfirmAccount(string ID)
    {
        if (string.IsNullOrEmpty(ID) || (!Regex.IsMatch(ID,
                        @"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}")))
        {
            TempData["tempMessage"] =
                "The user account is not valid. Please try clicking the link in your email again.";
            return View();
        }
        MembershipUser user = Membership.GetUser(new Guid(ID));

        if (!user.IsApproved)
        {
            user.IsApproved = true;
            Membership.UpdateUser(user);
            FormsAuthentication.SetAuthCookie(user.UserName, false);
            return RedirectToAction("Login");
        }
        WebSecurity.Logout();
        TempData["tempMessage"] = "You have already confirmed your email address... please log in.";
        return RedirectToAction("Login");
    }      

Could anyone please show me how to make this work, or perhaps suggest a different way to make this work??

Was it helpful?

Solution

I encourage you to use Postal, which is a simple to use email-creation package. It's available as a nuget-package.

Also take a look at Kevin Junghans blogpost on the subject! Email confirmation

OTHER TIPS

I have done the following and it is working:

Create the token in the Register as :

string confirmationToken =
                        WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email }, true);

Then in the confirmation used the following:

public ActionResult RegisterConfirmation(string Id)
        {
            if (WebSecurity.ConfirmAccount(Id))
            {
                return RedirectToAction("ConfirmationSuccess");
            }
            return RedirectToAction("ConfirmationFailure");
        }

Error message from your edit sounds like your local machine is not listening neither on port 25 nor 587. I think you should check if the SMTP server is configured and running before doing anything with your code.

You can simply create 2 accounts on this local server and set them up in any email client and check if you're able to send emails between them. Second option is checking connection using telnet, but I have not tried it - http://www.petri.co.il/test_smtp_service.htm

If using mail server outside of your app was successfull and you still have errors, be sure that your WebMail.UserName and WebMail.Password are correct. If yes, try setting WebMail.From to one of local test email addresses that you're using in WebMail configuration, like test@localhost or test@127.0.0.1 (I had to use IP to pass email validation sometimes).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top