如何在MVC4中使确认链接激活账户?

4
我正在构建一个MVC 4应用程序,从默认的互联网应用程序开始。我的目标是在用户注册网站时向他们发送确认电子邮件,我已经成功发送了确认电子邮件,但是当我点击它时,帐户并没有被确认。
注意:我知道Register操作很拥挤,当我使其工作时,我将把它分成不同的文件。
这是我所做的:
注册操作
[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));
            }
        }

确认账户操作。
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");            
    }

也尝试过
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");
    }      

请问有人可以告诉我如何让这个工作起来,或者建议其他方法使其正常工作吗?

1
指定的字符串是什么?model.UserName 是否以 someone@somewhere.com 的形式呈现? - Robert Harvey
@levelnis 请看上面的编辑,尽管没有进行开发,但仍然会出现错误。错误发生在相同的代码处。 - Komengem
1
也许这是一个愚蠢的问题,但是你在本地机器上设置了邮件服务器吗? - Konrad Gadzina
@KonradGadzina 是的,我使用了 Postal……我已经在下面标记了答案,请跟随链接到 Kevin 的博客,但也请阅读评论,我自己留了一些评论,这可能对使其在网络上工作至关重要。 - Komengem
@KomengeMwandila 太好了!如果需要的话我会检查它。感谢您的评论,否则我可能会错过解决方案。 - Konrad Gadzina
显示剩余5条评论
3个回答

7
我建议您使用 Postal,这是一个易于使用的电子邮件创建包。它作为nuget包提供。
同时,您也可以查看Kevin Junghans关于此主题的博客文章!电子邮件确认

是的,我正在查看Postal和Kevin的博客。谢谢。 - Komengem
嘿Komenge,我有一个疑问 - 现在用户帐户已经确认 - 我想再次将其设置为待定状态,以便稍后再次确认..请告诉我如何做? - Vitthal
+!用于邮政编码的...非常有用的包。谢谢。 - iCollect.it Ltd

1
我已经完成以下操作并且它正在运行:
在注册中创建令牌,方法如下:
string confirmationToken =
                        WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email }, true);

然后在确认中使用以下内容:
public ActionResult RegisterConfirmation(string Id)
        {
            if (WebSecurity.ConfirmAccount(Id))
            {
                return RedirectToAction("ConfirmationSuccess");
            }
            return RedirectToAction("ConfirmationFailure");
        }

0

你的编辑器返回的错误信息似乎是你的本地机器没有监听 25587 端口。在处理代码之前,我认为你应该检查 SMTP 服务器是否已配置和运行。

你可以在本地服务器上创建两个帐户,并在任何电子邮件客户端中设置它们,检查是否能够在它们之间发送电子邮件。第二个选项是使用 telnet 检查连接,但我还没有尝试过 - http://www.petri.co.il/test_smtp_service.htm

如果在应用程序外部使用邮件服务器成功并且仍然出现错误,请确保你的 WebMail.UserNameWebMail.Password 是正确的。如果是,尝试将 WebMail.From 设置为你在 WebMail 配置中使用的本地测试电子邮件地址之一,例如 test@localhosttest@127.0.0.1(有时我不得不使用 IP 来通过电子邮件验证)。


我就是不明白为什么本地主机上的端口25无法工作。这是我所知道的唯一一个在本地机器上用于Smpt电子邮件的端口。我认为我的代码有问题。不管怎样,我刚刚收到了我的Pro ASP.NET MVC4书籍,我会查看里面是否有类似的内容。 - Komengem
@KomengeMwandila 但是你是否像我建议的那样检查了SMTP服务器是否正常工作?首先检查它,如果它正常工作,再检查你的代码。 - Konrad Gadzina
我已经将端口更改为我的应用程序端口,现在出现了“操作已超时”的错误,并且所有错误都发生在“WebMail.Send”处。 - Komengem
@KomengeMwandila,您遇到了不同的错误,因为您的应用程序端口上有一个正在运行的服务 - 它是应用程序服务器,并且操作已超时,因为此服务未创建以处理SMTP请求。请使用我发布的其中一种方式检查您的SMTP服务器是否正在运行。SMTP 应该在端口 25 上。错误消息 No connection could be made because the target machine actively refused it 127.0.0.1:PORT 意味着没有服务在此端口上监听或防火墙引起问题。但由于这是您的本地开发机器,所以防火墙不应该是问题。 - Konrad Gadzina

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接