top of page

Xây dựng tính năng gửi Mail trong ASP.NET

  • Writer: PhongPX
    PhongPX
  • Oct 19, 2020
  • 5 min read

Xin một lời khẳng định chắc nình nịch từ mình là bây giờ hầu hết các trang web bây giờ, kể cả trang web giải trí hay trang web doanh nghiệp thì tính năng gửi mail không nhiều thì ít luôn có đất cho nó dụng võ. Cụ thể thì nó dành cho những việc như: Xác thực, Thay đổi mật khẩu, Thông báo ... Trong quá trình mình thực tập và đi thử việc thì đã tích góp được một số kinh nghiệm và kiến thức để có thể xây dựng một tính năng gửi mail hoàn chỉnh. Các bạn cùng ghé đọc và góp ý giúp mình nha.


Ý tưởng

  • Tính năng gửi mail mình xây dựng là để lấy lại mật khẩu cho người dùng hệ thống.

  • Đầu tiên để có thể gửi mail được thì mình phải bắt người dùng nhập vào tên đăng nhập hệ thống (User Name) và Email muốn lấy lại mật khẩu (Điều kiện cho email này mình sẽ nói sau).

  • Vậy sau khi nhập đầy đủ 2 trường thì email trả về sẽ bao gồm Tên người dùng và mật khẩu mới cho người dùng có thể đăng nhập.

Triển khai


Bước 1: Xây dựng giao diện

Như mình đã nói, giao diện chỉ có 2 trường là UserName và Email. Code triển khai như sau:


<div class="panel-body">
 <div class="form-group">
 <div class="col-md-12">
 <asp:TextBox ID="txtUserName" CssClass="form-control" runat="server" placeholder="Tên đăng nhập" Style="font-size: 1rem !important; height: calc(2rem + 2px)!important"
 Width="100%"></asp:TextBox>
 </div>
 </div>
 <div class="form-group">
 <div class="col-md-12">
 <asp:TextBox ID="txtEmail" CssClass="form-control" runat="server" Style="font-size: 1rem !important; height: calc(2rem + 2px)!important"
 placeholder="Email" Width="100%"></asp:TextBox>
 </div>
 </div>
 <div class="form-group">
 <asp:Label ID="lblerror" runat="server" Text="" ForeColor="red"></asp:Label>
 </div>
 <div class="form-group">
 <div class="col-md-4 " style="text-align: left">
 <asp:Button ID="btnLogin" runat="server" Text="Gửi yêu cầu" CssClass="btn btn-primary" Style="font-size: 1rem !important;"
 OnClientClick="return checkInput();" OnClick="btnLogin_Click" />
 </div>
 </div>
</div>

Hàm quan trọng nhất ở đây chính là hàm CheckInput. Mình sẽ viết sự kiện CheckInput bao gồm kiểm tra tính đúng đắn của trường Email và mặc định không được bỏ trống giá trị các trường như sau:


<script type="text/javascript">

 function checkInput() {
 var UserName = document.getElementById("<%=txtUserName.ClientID %>").value;
 var Email = document.getElementById("<%=txtEmail.ClientID %>").value;
 var error = document.getElementById("<%=lblerror.ClientID %>");


 if (UserName == null || UserName == '' || UserName.length < 1) {
 error.innerHTML = "Vui lòng nhập tên đăng nhập";
 return false;
  }
 var re = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
 if (!re.test(Email)) {
 error.innerHTML = "Vui lòng nhập đúng Email";
 //alert(re.test(Email));
 return false;
  }
 return true;
}
</script>

Vậy là hoàn thành bước giao diện, bây giờ cùng chuyển sang bước khó hơn là xử lý gửi mail.


Bước 2: Xử lý code behind để gửi mail.

Như các bạn đã từng thấy, mật khẩu sau khi lấy lại của hệ thống nó là một chuỗi số bất kì dạng như sau: Xqw12U7.... Vậy để có thể lấy ra được những kiểu mật khẩu na ná như vậy, mình sẽ xây dựng 1 hàm có tên là GenerateRandomCode.

private string GenerateRandomCode()
        {
            Random r = new Random();
            string s = "";
            for (int j = 0; j < 7; j++)
            {
                int i = r.Next(3);
                int ch;
                switch (i)
                {
                    case 1:
                        ch = r.Next(0, 9);
                        s = s + ch.ToString();
                        break;
                    case 2:
                        ch = r.Next(65, 90);
                        s = s + Convert.ToChar(ch).ToString();
                        break;
                    case 3:
                        ch = r.Next(97, 122);
                        s = s + Convert.ToChar(ch).ToString();
                        break;
                    default:
                        ch = r.Next(97, 122);
                        s = s + Convert.ToChar(ch).ToString();
                        break;
                }
                r.NextDouble();
                r.Next(100, 1999);
            }
            return s;
        }

Sau đó, mình kiểm tra xem trong cơ sở dữ liệu mình có tồn tại UserName và có Email tương ứng như vậy không. Nếu có thì xử lý tiếp, còn không thì báo lỗi nhập cho người dùng biết.

Domain.User usr = new UserService().GetByUserEmail(txtUserName.Text.Trim(), txtEmail.Text.Trim());
  if (usr != null && CGlobal.ToInt(usr.Id) >0)
     {
	...Code xử lý tại đây !
     }
  else
     { 
        lblerror.Text = "Tên đăng nhập hoặc Email không đúng";
     }

Sau khi check các trường hợp xong, thì mình bắt đầu vô cấu hình Email để gửi, phần này hơi phức tạp tí nhưng mình sẽ cố nói rõ ràng trong code luôn.


Thư viện sử dụng là:

using System.Net.Mail;

Code xử lý như sau:

// Sau khi có mã Random, sử dụng mã hóa MD5 để lấy Password cuối cùng
string password = GenerateRandomCode();
usr.Password = Library.Encryption.MD5.Encrypt(usr.UserName + password);

MailMessage mail = new MailMessage();

//Thiết lập Email gửi đi bao gồm các trường như: Người gửi, người nhận, Title..
Domain.EmailConfig obj = new EmailConfigService().GetListByComapaniId(0, "2");
mail.From = new MailAddress(obj.Email);
mail.To.Add(new MailAddress(usr.Email));
mail.IsBodyHtml = true;
mail.Subject = obj.Title;

//Thiết lập nội dung Email và tiến hành gửi
Domain.Customer objCus = new CustomerService().GetById(CGlobal.ToInt(usr.CustomerId));
mail.Body = obj.Containt.Replace("[UserName]", usr.UserName).Replace("[Password]", password).Replace("[CompanyName]", objCus.Name).Replace("[Taxcode]", objCus.Taxcode);
SmtpClient client = new SmtpClient();
client.Port = CGlobal.ToInt(obj.Port);
client.Host = obj.ServerMail;
client.Timeout = 10000;
if (obj.MailType == "SSL")
  {
   client.EnableSsl = true;
  }
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential(obj.Email, CGlobal.Base64Decode(obj.PasswordEmail));
client.Send(mail);

//Sau khi gửi xong, update lại mật khẩu lại cho User đó và quay lại trang Login.
new UserService().Update(usr);
Response.Redirect("Login.aspx", false);

Hàm quan trọng nhất đã được mình tô màu đỏ ở trên. vậy hàm đó được xử lý như thế nào, cùng đi sau vào nhé


Domain.EmailConfig obj = new EmailConfigService().GetListByComapaniId(0, "2");


Mục đích của câu lệnh trên chính là đọc dữ liệu của cấu hình mail chủ, nó bao gồm như Tên người gửi, Title, Port, ServerMail. 2 đối số được truyền vô là 0 và 2 nhằm mục đích là lấy đúng dữ liệu cho mail chủ. Cụ thể ở đây mình gán 0 chính là CustomerID, còn 2 chính là Type. Cái này là do thiết kế DB quy định chớ không nhất thiết phải truyền đối số như vậy.

Tùy vào DB bạn cấu hình ra sao, thì bạn truyền đối số như vậy để lấy cho đúng dòng dữ liệu cần lấy.


Mình sẽ viết 1 Procedure có tên là _prottblEmailConfig_GetListByComapaniId, sau đó gọi nó để lấy như sau:

ALTER procEDURE [dbo].[_prottblEmailConfig_GetListByComapaniId]
	-- Add the parameters for the stored procedure here
@CustomerId int,
@Type	char(1)
	
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

    -- Insert statements for procedure here
	SELECT * from tblEmailConfig 	
	where (@Type='' or Type = @Type) and (CustomerId=@CustomerId)
END	

Dòng dữ liệu cần lấy sau khi procedure được gọi có dạng như sau:


Gọi Procedure trong chương trình như sau:


Chú ý là bạn phải tạo một model EmailConfig để chứa dữ liệu trước khi gọi nha, có các trường tương ứng với các trường trong Database nhé.



Ngoài ra, nếu bạn thắc mắc câu lệnh

Domain.Customer objCus = new CustomerService().GetById(CGlobal.ToInt(usr.CustomerId));

dùng để làm gì thì nó cũng tương tự câu lệnh mình đã giải thích, nhưng với mục đích là lấy CompanyName để gắn trường đó vô MailBody.

Tuy nhiên tùy vào nội dung mail mà bạn có thể bỏ qua trường này.

Email gửi cho khách hàng chỉ cần UserName và Password là đủ, không cần thêm trường Company Name là gì cho nó phức tạp ra.


Kết quả

Sau khi hoàn thành thì Email khách hàng nhận được sẽ như trên. Chỉ cần bạn gửi thêm đường link đăng nhập thêm vào MailBody rồi đưa là một dòng thông báo là nếu muốn đăng nhập thì click vô đường link ấy. Vậy là xong.


Vậy là mình đã giới thiệu sơ qua về cách viết một tính năng gửi Email lấy lại mật khẩu trong ASP.NET. Chắc chắn còn nhiều sai sót và khó hiểu do đó nếu bạn hứng thú thì có thể để lại bình luận bên dưới để chúng ta có thể trao đổi.

PEACE

Comments


Liên lạc tôi bằng cách dưới đây nha !

Thanks for submitting!

bottom of page