Tạo lớp ConfigSection.cs trong thư mục App_Code và viết code như sau: namespace KimSoft { /// /// Lớp KimSoftSection kế thừa từ lớp ConfigurationSection /// Chứa các thuộc tính cấu
Trang 1Chương 3 Planning an Architecture
***
1 Tạo lớp ConfigSection.cs trong thư mục App_Code và viết code như sau:
namespace KimSoft
{
/// <summary>
/// Lớp KimSoftSection kế thừa từ lớp ConfigurationSection
/// Chứa các thuộc tính cấu hình của website và các phương thức (get, set) tương ứng
/// </summary>
public class KimSoftSection : ConfigurationSection
{
//Chuỗi kết nối dữ liệu
[ConfigurationProperty("defaultConnectionStringName", DefaultValue =
"LocalSqlServer")]
public string DefaultConnectionStringName
{
get { return (string)base["defaultConnectionStringName"]; }
set { base["connectionStdefaultConnectionStringNameringName"] = value; } }
//Thời gian Cache dữ liệu (đơn vị là giây)
[ConfigurationProperty("defaultCacheDuration", DefaultValue = "600")]
public int DefaultCacheDuration
{
get { return (int)base["defaultCacheDuration"]; }
set { base["defaultCacheDuration"] = value; }
}
//Các thuộc tính trong trang Contact.aspx
[ConfigurationProperty("contactForm", IsRequired = true)]
public ContactFormElement ContactForm
{
get { return (ContactFormElement)base["contactForm"]; }
}
}
/// <summary>
/// Lớp ContactFormElement kế thừa từ lớp ConfigurationElement
/// chứa các thuộc tính của một gói mail
/// </summary>
public class ContactFormElement : ConfigurationElement
{
//Chủ đề
[ConfigurationProperty("mailSubject", DefaultValue = "Mail from KimSoft: {0}")] public string MailSubject
{
get { return (string)base["mailSubject"]; }
set { base["mailSubject"] = value; }
}
Trang 2//Email nhận
[ConfigurationProperty("mailTo", IsRequired = true)]
public string MailTo
{
get { return (string)base["mailTo"]; }
set { base["mailTo"] = value; }
}
//Email CC
[ConfigurationProperty("mailCC")]
public string MailCC
{
get { return (string)base["mailCC"]; }
set { base["mailCC"] = value; }
}
//Email gởi (mailFrom được lưu trong file web.config)
}
}
2 Lớp KimSoftSection được ánh xạ với section <KimSoft> trong file web.config như sau:
Khai báo section tên KimSoft trong configSection
Định nghĩa section KimSoft
<! Khai báo section KimSoft >
<section name= KimSoft" type= KimSoft.KimSoftSection, code" />
<! Định nghĩa section KimSoft >
<KimSoft defaultConnectionStringName= LocalSqlServer">
<contactForm mailTo= longnamit@yahoo.com" />
</KimSoft>
Trang 33 Thêm vào public field of type KimSoftSection bên trong lớp Globals như sau:
namespace KimSoft {
public static class Globals
{
public static string ThemesSelectorID = "";
//Khai báo và khởi tạo biến tĩnh (static) chỉ đọc (readonly) Settings kiểu
KimSoftSection
// Giá trị khởi tạo được lấy từ file web.config thông qua lớp
WebConfigurationManager
public readonly static KimSoftSection Settings = (KimSoftSection)WebConfigurationManager.GetSection("KimSoft");
}
}
4 Thêm vào namespace System.Web.Configuration cho WebConfigurationManager
using System.Web.Configuration;//WebConfigurationManager
5 Thêm code vào trang Contact.aspx như sau:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Contact.aspx.cs"
Inherits ="KimSoft.UI.Contact" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="LeftContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<! Textbox nhập tên >
Your name: <asp:TextBox runat="server" ID="txtName" Width="100%" />
<! Bắt buộc nhập tên >
<asp:RequiredFieldValidator runat="server"
Display="dynamic"
ID="valRequireName"
SetFocusOnError="true"
ControlToValidate="txtName"
ErrorMessage="Your name is required">*
</asp:RequiredFieldValidator>
<! Textbox nhập email >
Your e-mail: <asp:TextBox runat="server" ID="txtEmail" Width="100%" />
<! Bắt buộc nhập email >
<asp:RequiredFieldValidator runat="server"
Display="dynamic"
ID="valRequireEmail"
SetFocusOnError="true"
ControlToValidate="txtEmail"
ErrorMessage="Your e-mail address is required">*
</asp:RequiredFieldValidator>
<! Kiểm tra email có hợp lệ không? >
<asp:RegularExpressionValidator runat="server"
Trang 4Display="dynamic"
ID="valEmailPattern"
SetFocusOnError="true"
ControlToValidate="txtEmail"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
ErrorMessage="The e-mail address you specified is not well-formed">*
</asp:RegularExpressionValidator>
<! Textbox nhập chủ đề >
Subject: <asp:TextBox runat="server" ID="txtSubject" Width="100%" />
<! Bắt buộc nhập chủ đề >
<asp:RequiredFieldValidator runat="server"
Display="dynamic"
ID="valRequireSubject"
SetFocusOnError="true"
ControlToValidate="txtSubject"
ErrorMessage="The subject is required">*
</asp:RequiredFieldValidator>
<! Textbox nhập nội dung >
Body: <asp:TextBox runat="server"
ID="txtBody"
Width="100%"
TextMode="MultiLine"
Rows="8" />
<! Bắt buộc nhập nội dung >
<asp:RequiredFieldValidator runat="server"
Display="dynamic"
ID="valRequireBody"
SetFocusOnError="true"
ControlToValidate="txtBody"
ErrorMessage="The body is required">*
</asp:RequiredFieldValidator>
<! Label thông báo gởi email thành công >
<asp:Label runat="server"
ID="lblFeedbackOK"
Visible="false"
Text="Your message has been successfully sent."
SkinID="FeedbackOK" />
<! Label thông báo gởi mail không thành công >
<asp:Label runat="server"
ID="lblFeedbackKO"
Visible="false"
Text="Sorry, there was a problem sending your message."
SkinID="FeedbackKO" />
<! Button gởi mail >
<asp:Button runat="server" ID="txtSubmit" Text="Send" OnClick="txtSubmit_Click" />
<! Thông báo tổng hợp các textbox bắt buộc mà chưa nhập >
<asp:ValidationSummary runat="server"
ID="valSummary"
ShowSummary="false"
ShowMessageBox="true" />
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="RightContent" Runat="Server">
</asp:Content>
6 Viết code cho sự kiện txtSubmit_Click
Trang 5 Double-click vào button Send để phát sinh sự kiện txtSubmit_Click
Viết code cho sự kiện txtSubmit_Click như sau:
namespace KimSoft.UI
{
public partial class Contact : BasePage
{
protected void Page_Load(object sender, EventArgs e){ }
protected void txtSubmit_Click(object sender, EventArgs e)
{
try
{
// Khai báo gói tin (email)
MailMessage msg = new MailMessage();
// Nội dung (Body) là text thông thường không phải code HTML
msg.IsBodyHtml = false;
// Email, tên của người gởi lấy từ text box txtEmail và txtName
msg.From = new MailAddress(txtEmail.Text, txtName.Text);
// Email của người nhận lấy từ file web.config thông qua lớp Globals
msg.To.Add(new MailAddress(Globals.Settings.ContactForm.MailTo));
// Nếu MailCC khác NULL hay khác rỗng thì thêm MailCC vào gói tin
if (!string.IsNullOrEmpty(Globals.Settings.ContactForm.MailCC))
msg.CC.Add(new MailAddress(Globals.Settings.ContactForm.MailCC)); // Chủ đề lấy từ text box txtSubject
msg.Subject = string.Format(Globals.Settings.ContactForm.MailSubject, txtSubject.Text);
// Nội dung tin lấy từ text box txtBody
msg.Body = txtBody.Text;
// Khai báo và khởi tạo biến SmtpClient
SmtpClient smtp = new SmtpClient();
//Gởi gói tin
smtp.Send(msg);
// Hiển thị thông báo gởi mail thành công
lblFeedbackOK.Visible = true;
lblFeedbackKO.Visible = false;
//Reset lại các text box
txtName.Text = "";
txtEmail.Text = "";
txtSubject.Text = "";
txtBody.Text = "";
}
catch (Exception)
{
// Hiển thị thông báo gởi mail không thành công
lblFeedbackOK.Visible = false;
lblFeedbackKO.Visible = true;
}
}
}
}
Thêm vào thư viện:
using System.Net.Mail;//MailMessage, MailAddress, SmtpClient
Trang 67 Chạy và kiểm tra chương trình
8 Thiết lập giao thức SMTP để send message, định nghĩa SMTP trong file web.config file như sau:
<configuration>
<system.net>
<mailSettings>
<smtp deliveryMethod= Network" from ="webmaster@kimsoft.com.vn">
<network defaultCredentials= true" host= (localhost)" port= 25"
/>
</smtp>
</mailSettings>
</system.net>
</configuration>
9 Cài đặt và cấu hình SMTP Service (nếu máy của bạn chưa có – Xem phụ lục kèm theo chương 3)
10 Tạo thư mục DAL trong thư mục App_Code/DAL
11 Tạo lớp DataAccess trong thư mục App_Code/DAL/DataAccess.cs Và viết code như sau:
namespace KimSoft.DAL
{
/// <summary>
/// Lớp DataAccess là lớp trừu tượng (abstract class)
/// </summary>
public abstract class DataAccess
{
//Thuộc tính chuỗi kết nối
private string _connectionString = "";
protected string ConnectionString
{
get { return _connectionString; }
set { _connectionString = value; }
}
//Thuộc tính EnableCaching(true, false) cho phép Caching hay không
private bool _enableCaching = true;
protected bool EnableCaching
{
get { return _enableCaching; }
set { _enableCaching = value; }
}
//Thuộc tính CacheDuration
private int _cacheDuration = 0;
protected int CacheDuration
{
get { return _cacheDuration; }
set { _cacheDuration = value; }
}
//Trả về Cache
protected Cache Cache
{
Trang 7get { return HttpContext.Current.Cache; }
}
/// <summary>
/// Thực thi DML store
/// </summary>
/// <param name="cmd"></param>
/// <returns></returns>
protected int ExecuteNonQuery(DbCommand cmd)
{
if (HttpContext.Current.User.Identity.Name.ToLower() == "sampleeditor")
{
foreach (DbParameter param in cmd.Parameters)
{
if (param.Direction == ParameterDirection.Output ||
param.Direction == ParameterDirection.ReturnValue)
{
switch (param.DbType)
{
case DbType.AnsiString:
case DbType.AnsiStringFixedLength:
case DbType.String:
case DbType.StringFixedLength:
case DbType.Xml:
param.Value = "";
break;
case DbType.Boolean:
param.Value = false;
break;
case DbType.Byte:
param.Value = byte.MinValue;
break;
case DbType.Date:
case DbType.DateTime:
param.Value = DateTime.MinValue;
break;
case DbType.Currency:
case DbType.Decimal:
param.Value = decimal.MinValue;
break;
case DbType.Guid:
param.Value = Guid.Empty;
break;
case DbType.Double:
case DbType.Int16:
case DbType.Int32:
case DbType.Int64:
param.Value = 0;
break;
default:
param.Value = null;
break;
}
}
}
return 1;
}
else
Trang 8return cmd.ExecuteNonQuery();
}
/// <summary>
/// Thực thi câu lệnh select store behavior mặc định
/// trả về 1 danh sách đối tượng lưu trong IDataReader
/// </summary>
/// <param name="cmd"></param>
/// <returns></returns>
protected IDataReader ExecuteReader(DbCommand cmd)
{
return ExecuteReader(cmd, CommandBehavior.Default);
}
/// <summary>
/// Thực thi câu lệnh select store theo tham số behavior
/// trả về 1 danh sách đối tượng lưu trong IDataReader
/// </summary>
/// <param name="cmd"></param>
/// <param name="behavior"></param>
/// <returns></returns>
protected IDataReader ExecuteReader(DbCommand cmd, CommandBehavior behavior) {
return cmd.ExecuteReader(behavior);
}
/// <summary>
/// Thực thi câu lệnh select store trả về 1 giá trị
/// </summary>
/// <param name="cmd"></param>
/// <returns>object</returns>
protected object ExecuteScalar(DbCommand cmd)
{
return cmd.ExecuteScalar();
}
}
}
12 Thêm vào 2 namespace sau cho Cach và DbCommand:
using System.Web.Caching;//Cache
using System.Data.Common;//DbCommand
13 Tạo thư mục BLL trong thư mục App_Code
14 Tạo lớp BizObject.cs trong thư mục App_Data/BLL/ định nghĩa một số thuộc tính, phương thức thường xuyên được sử dụng bởi những đối tượng khác trong BLL như sau:
namespace KimSoft.BLL
{
public abstract class BizObject
{
// Hằng số (const) MAXROWS
// int.MaxValue = 65.536
protected const int MAXROWS = int.MaxValue;
Trang 9// Trả về Cache
protected static Cache Cache
{
get { return HttpContext.Current.Cache; }
}
//Lấy thông tin của User hiện tại
protected static IPrincipal CurrentUser
{
get { return HttpContext.Current.User; }
}
//Lấy tên của User hiện tại
protected static string CurrentUserName
{
get
{
string userName = "";
if (HttpContext.Current.User.Identity.IsAuthenticated)
userName = HttpContext.Current.User.Identity.Name;
return userName;
}
}
//Lấy IP của User hiện tại
protected static string CurrentUserIP
{
get { return HttpContext.Current.Request.UserHostAddress; }
}
/// <summary>
/// Trả về chỉ số trang
/// </summary>
/// <param name="startRowIndex"></param>
/// <param name="maximumRows"></param>
/// <returns>int</returns>
protected static int GetPageIndex(int startRowIndex, int maximumRows)
{
if (maximumRows <= 0)
return 0;
else
return (int)Math.Floor((double)startRowIndex / (double)maximumRows); }
//Chuyển nội dung thông thường thành đoạn mã HTML
protected static string EncodeText(string content)
{
content = HttpUtility.HtmlEncode(content);
content = content.Replace(" ", " ").Replace("\n", "<br>");
return content;
}
//Chuyển giá trị Null thành giá trị chuỗi rỗng
protected static string ConvertNullToEmptyString(string input)
{
return (input == null ? "" : input);
}
// Làm sạch Cache bằng cách xoá các Cache Item có prefix input
protected static void PurgeCacheItems(string prefix)
{
prefix = prefix.ToLower();
List<string> itemsToRemove = new List<string>();
Trang 10IDictionaryEnumerator enumerator = BizObject.Cache.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().ToLower().StartsWith(prefix))
itemsToRemove.Add(enumerator.Key.ToString());
}
foreach (string itemToRemove in itemsToRemove)
BizObject.Cache.Remove(itemToRemove);
}
}
}
15 Thêm vào các namespace sau:
using System.Web.Caching;//Cach
using System.Security.Principal;//IPrincipal
using System.Collections.Generic;//List
using System.Collections;//IDictionaryEnumerator
16 Tạo thư mục Bin cho project
Right-click project, chọn Add ASP.NET Folder Bin
17 Copy file MB.TheBeerHouse.CustomEvents.dll vào thư mục Bin của KimSoft
18 Thêm đoạn code sau vào file web.config giữa <system.web></system.web> để log lại các thao tác delete của Admin hay Editor:
</system.web>
<healthMonitoring heartbeatInterval= 10800" >
<providers>
<remove name= SqlWebEventProvider" />
<add name= SqlWebEventProvider" connectionStringName= LocalSqlServer"
buffer= false" bufferMode= Notification"
maxEventDetailsLength= 1073741823"
type= System.Web.Management.SqlWebEventProvider,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
<eventMappings>
<add name= TBH Events"
type= MB.TheBeerHouse.WebCustomEvent, MB.TheBeerHouse.CustomEvents" />
</eventMappings>
<rules>
<clear />
<add name= TBH Events" eventName= TBH Events"
provider= SqlWebEventProvider" profile= Critical" />
<add name= All Errors" eventName= All Errors"
provider= SqlWebEventProvider" profile= Critical" />
<add name= Failure Audits" eventName= Failure Audits"
provider= SqlWebEventProvider" profile= Critical" />
<add name= Heartbeats" eventName= Heartbeats"