Search code examples
htmlasp.net-mvc-4hyperlinkasp.net-core-2.0asp.net-mvc-routing

Generate <a> link in controller to send in email


I'm implementing a password reset system, and while the code is working fine, there's a small problem... with the users. The system works by generating single-use crypto-secure tokens which are sent via email. The problem is that to use these tokens, the user must then click on a link in the email they receive. This in itself isn't a problem, but the link in question looks something like this:

http://www.example.com/Account/ResetPassword/184?t=BC2EveZtRl3wjbONboalzlUVwUpp%252BYaiKvbsZ6aPPYE%253D

The users are reluctant to click on this link because it's big and scary-looking; they think it's a trick by some malicious third party to steal their password or give them a virus or something.

If this was a view, I'd use @Html.ActionLink() to generate a pretty <a> link that said "Click here to reset your password", and that'd be fine. In a controller, however, I don't have access to that method unless I instantiate a HtmlHelper, which requires ViewData, which leads to a whole chain of things that need to be instantiated to fake up some stuff that I won't use anyway, and everywhere I've looked says that this is bad practice and I shouldn't do it.

What's the cleanest way to generate a neat <a> link, in controller code, in ASP.NET MVC?


Solution

  • The UrlHelper is available in a controller via the Url property, that can do the same thing, and that is to build a url for you. So you can feed your email sender a text that include a link and this is how you build that part of the email:

    var link = "<a href='http://www.mysite.com/" 
        + @Url.Action("ResetPassword","Account", new{id=184, t=token}) 
        +"'>Click here to reset your password</a>"
    // where token is your single-use crypto-secure
    

    If you want the domain to be dynamic then you can change it to:

    var link = "<a href='" 
        + Request.Url.Scheme + "://"
        + Request.Url.Authority
        + @Url.Action("ResetPassword","Account", new{id=184, t=token}) 
        +"'>Click here to reset your password</a>"
    // where token is your single-use crypto-secure