GIẢI PHÁP CHỢ ĐIỆN TỬ 3.1Giới thiệu ứng dụng
3.2.2 Kiến trúc Chợ Điện Tử
Ứng dụng chợ điện tử bao gồm 4 dự án (project) như hình:
Hình 3.6 Các dự án được sử dụng trong “Chợ điện tử”
Các dự án được xây dựng bên trong “Chợ điện tử” gồm: dự án Application (Application Project), dự án DataProvider (DataProvider Project), dự án Controls (Controls Project) và cơ sở dữ liệu. Các dự án và cơ sở dữ liệu trong mô hình “Chợ” điện tử” có sự tương tác, kết hợp lẫn nhau, sau đây là mô hình:
Dự án Application được xây dựng từ các Control của dự án Control. Các phương thức của dự án Controls được kết hợp với các phương thức Components để thực hiện các thao tác xử lý Control. Khi các sự kiện Control trong dự án được phát sinh, các sự kiện này sẽ kết hợp với các phương thức của dự án DataProvider để lấy tạo nên một sự tương tác với cơ sở dự liệu. Dự án DataProvider là cầu nối quan trọng giữa cơ sở dự liệu và các dự án khác.
Ưu điểm của việc phân chia ứng dụng chợ điện tử thành các project nhỏ so với cách viết website thông thường:
Việc phân chia các dự án đảm bảo được mô hình ba tầng khi xây dựng và triển khai một ứng dụng web.
Việc phân chia các project như vậy làm cho việc xây dựng ứng dụng “Chợ điện tử” được dễ dàng, có một sự rõ ràng trong định hướng, làm khâu viết code không bị chồng chéo.
Các dự án sau khi xây dựng có khả năng tái sử dụng vào các ứng dụng xây dựng website khác, các nhà lập trình web có thể kế thừa để phát triển thêm các ứng dụng riêng.
• Dự án Application (Application Project)
Dự án Application là dự án để chạy ứng dụng website trang chợ điện tử. Trong dự án này chứa các tập tin như *.aspx, *.ascx, .... và đặc biệt là chứa các file *.dll đã được biên dịch từ các file code dạng *.cs của các dự án Controls, dự án Components, dự án DataProvider. Các file *.dll này bao gồm: Controls.dll, Components.dll,
DataProvider.dll. Các file *.dll được biên dịch sẽ được lưu trữ tại thư mục Bin của dự án Application nhằm mục đích để Framework của .NET đọc các lớp code từ các file này phục vụ cho việc xử lý, hiển thị các trang website.
Hình 3.8 Các file *.dll được lưu trữ tại thư mục Application/Bin của dự án Application
Để sử dụng được các file *.dll trong ứng dụng, phải thêm các thể hiển của file này trong tập tin web.config. Cách thêm như thế này giúp đọc các lớp, các phương thức chứa trong file *.dll được xuyên suốt trong ứng dụng mà không cần phải gọi lại các lớp, các phương thức này nhiều lần trong ứng dụng. Điều này giúp tiết kiệm thời gian cho người lập trình viên khi viết web.
Hình 3.9 Các file *.dll được nhúng trong tập tin web.config
TagPrefix là tên thẻ tiền tố biểu thị cho không gian tên (Namespace) của một file *.dll được sử dụng khi nhúng một lớp code kiểu control vào trang *.aspx hoặc trang *.ascx.
Assembly biểu thị cho các tập tin dạng dll, một assembly được xem như là một đơn vị.
Namespace là không gian tên chứa trong tập tin dạng dll cần sử dụng, trong một tập tin dạng dll có thể chứa nhiều namespace.
Dùng kỹ thuật XML trong việc sử dụng đa ngôn ngữ
Trong dự án ứng dụng có sử dụng kỹ thuật XML để định dạng đa ngôn ngữ dùng trong website thông qua các tập tin được lưu trữ tại thư mục Application/Languages/
Hình 3.10 Một phần nội dung tập tin Vietnamese.xml để hiển thị giao diện tiếng Việt
Thuộc tính name định nghĩa trong thẻ resource được dùng để phân biệt trong việc lấy các dữ liệu hiển thị lên website. Ứng với thuộc tính name có giá trị “em_Search_Keyword” ta có dữ liệu “Từ khoá” với tập tin ngôn ngữ là tiếng Việt (nằm trong tập tin Vietnamese.xml). Với mỗi tập tin ngôn ngữ khác nhau (English.xml, Vietnamese.xml, ....), các thuộc tính name giống nhau nhưng với dữ liệu khác nhau để phục vụ cho các ngôn ngữ khác nhau. Như vậy với trường hợp ngôn ngữ là tiếng Anh (tập tin English.xml), giá trị name “em_Search_Keyword” sẽ có dữ liệu là “Keyword”.
Việc lấy các dữ liệu bằng thuộc tính name trong file XML được thực hiện thông qua các Control ResourceButton, ResourceLabel, ReosourceLinkButton trong dự án Controls và các lớp xử lý, phân tích file XML trong dự án Components. Lớp
ResourceManager.cs trong dự án Components là lớp chính của việc thao tác với XML dùng để quản lý nguồn tài nguyên trong ứng dụng.
Hình 3.11 - Mô hình luồng xử lý cho việc lấy dữ liệu từ tập tin XML ứng với ngôn ngữ Vietnames.xml
Luồng yêu cầu dữ liệu (luồng các mũi tên tô mảnh, hình 3.5 )
Khi một người truy cập trang web abc.aspx với thuộc tính ngôn ngữ là tiếng Việt. Khi đó .NET Framework phân tích code trang này và thấy có một Controls tên là ResourceLabel. Dựa vào Control này, .NET Framework chuyến đọc tới lớp ResourceLabel kèm theo thuộc tính ngôn ngữ trong dự án Controls. Lớp ResourceLabel triệu gọi một phương thức lấy dữ liệu từ file XML, thông qua phương thức này, tiếp tục các lớp ResourceManager.cs của dự án Components được gọi để xử lý tập tin Vietnamese.xml, tìm dữ liệu ứng với thuộc tính name. Lớp Cache.cs trong dự án Components góp phần lưu trữ dữ liệu giữa các lần gọi giúp ứng dụng chạy nhanh hơn.
Sau khi hoàn tất việc tìm kiếm thuộc tính name trong tập tin Vietnamese.xml. Nếu không có dữ liệu ứng với thuộc tính name này, phương thức tìm kiếm sẽ tự động quăng ra lỗi và trả về mô tả lỗi theo dòng in đậm trở về trình duyệt thông báo cho người sử dụng. Ngượcc lại, sẽ trả về kết quả theo dòng in đậm và hiển thị dữ liệu ứng với thuộc tính name đó trên website (trong trường hợp này dữ liệu là “Từ khoá”).
URL Rewriting dùng trong ứng dụng
Kỹ thuật URL Writing được dùng trong dự án Application nhằm giúp cho ứng dụng được hai thuộc tính lợi ích sau đây:
Tính tiện lợi
Người sử dụng internet luôn muốn truy cập vào các trang web có đường dẫn ngắn gọn, có quy tắc và dễ nhớ. Từ đó, kỹ thuật URL Rewriting được phát triển để loại bỏ những trang có đường dẫn dài, có nhiều tham số truy vấn, chuyển những trang web có đường dẫn phức tạp này về kiểu đơn giản. Kỹ thuật này giúp người sử dụng khi truy cập website tốn ít thời gian gõ tên đường dẫn mang lại tính tiện lợi khi truy cập website. So sánh hai đường dẫn sau đây:
Đường dẫn 1 http://www.somebloghost.com/Blogs/Posts.aspx?Year=2006&Month=12&Day=10 Đường dẫn 2 http://www.somebloghost.com/Blogs/2006/12/10/
Bảng 3.2 Bảng so sánh hai đường dẫn. Đường dẫn 1 không dùng kỹ thuật URL Rewriting, đường dẫn 2 dùng kỹ thuật URL Rewriting
Đường dẫn 2 dùng kỹ thuật URL Writing giúp người sử dụng dễ nhớ tên đường dẫn ngắn gọn hơn, thông qua các quy tắc dễ nhớ ngày, tháng, năm. Trong khi đó, đường dẫn 1 mang lại nhiều bất tiện.
Trong các website lớn, việc chuyển đổi các trang từ thư mục này sang thư mục khác sẽ gây một tác động nhất định đối với ứng dụng. Kết quả làm một số phần hoặc cả website không hoạt động.
Để dễ hiểu sự cố này, hình dung ví dụ có hai đường dẫn http://so.com/Info/Copyright.aspx và đường dẫn http://so.com/Support/Contacts.aspx. Người quản trị website đã di chuyển 2 trang Copyright.aspx và trang Contact.aspx đến thư mục mới tên là Help vào ngày hôm sau. Như vậy, người sử dụng internet đã lưu đường dẫn hai trang này trong ngày hôm trước tại lịch sử trình duyệt phải truy cập và lưu đường dẫn mới trong ngày hôm nay. Vấn đề này có thể được giải quyết bằng cách thêm một trang đệm chứa phương thức Response.Redirect(“tên đường dẫn”). Tuy nhiên, cách làm này không hiệu quả đối với việc di chuyển số lượng lớn (hàng trăm, hàng nghìn) các trang từ thư mục này sang thư mục khác trong ứng dụng. Do đó, kỹ thuật URL Rewriting giúp giải quyết vấn đề trên bằng cách chỉnh sửa đoạn code trong file *.config giúp người lập trình web di chuyển các trang giữa các thư mục ảo một cách nhanh chóng. Theo cách này, các nhà phát triển ứng dụng web có thể tách rời kiến trúc vật lý của website ra khỏi kiến trúc logic tới người dùng thông qua các URL. Nói tóm lại, kỹ thuật URL Rewriting góp phần làm duy trì website hoạt động ổn định.
Ánh xạ URL tự nhiên(native) trong ASP.NET 2.0
ASP.NET 2.0 cung cấp một giải pháp sáng tạo cho việc ánh xạ URL tĩnh đối với một ứng dụng Web. Việc ánh xạ URL cũ đến một URL mới bên trong tập tin web.config có thể được thực hiện mà không cần phải viết bất kỳ dòng lệnh nào cả. Để sử dụng việc ánh xạ URL, chỉ cần tạo một phần urlMapping bên trong phần system.web của tập tin web.config và thêm vào các yêu cầu cần ánh xạ. (đường dẫn dạng ~/ biểu thị cho thư mục gốc của ứng dụng web).
Hình 3.12 - Phần urlMapping bên trong file web.config
Vì vậy, nếu người sử dụng internet truy cập vào một đường dẫn có tên là: http://so.com/Support/Contacts.aspx thì người đó sẽ thấy ngay mộttrang mới có đường dẫn là: http://so.com/Help/Contacts.aspx mà không cần phải hiểu cơ chế trang cũ đã được ánh xạ tới trang mới.
Một điểm bất lợi khác của kỹ thuật ánh xạ URL tự nhiên là trường hợp nếu một trang có tên là Contacts.aspx chứa một số các yếu tố và bắt đầu postback về server (điều này hầu hết xảy ra), thì sau đó người sử dụng sẽ rất ngạc nhiên vì đường dẫn http://so.com/Support/Contacts.aspx bị thay đổi đến đường dẫn http://so.com/Help/Contacts.aspx (Hình .). Trong trường hợp này đáng lý đường dẫn cũ phải dẫn tới đường dẫn mới là http://www.simple-talk.com/Help/Contacts.aspx. Điều này bị xảy ra vì cơ chế của ASP.NET sẽ điền thuộc tính action trong thẻ HTML form với một đường dẫn thực đến một trang. Dạng form này được trả về mã HTML như sau:
Vì vậy, việc ánh xạ URL có sẵn trong ASP.NET 2.0 hầu hết là vô dụng. Việc chỉ rõ một tập hợp URL tương tự nhau trong một quy luật (rule) ánh xạ có thể được thực hiện tốt hơn. Giải pháp tốt nhất cho vấn đề này là sử dụng Regular Expression (được viết tắt là "RegEx" hoặc "regex" là một chuỗi được dùng để mô tả hoặc so sánh một tập chuỗi, theo các quy luật cú pháp nào đó) nhưng ASP.NET 2.0 không hỗ trợ Regular Expression. Vì vậy cần phải phát triển một giải pháp khác để tích hợp việc ánh xạ URL.
Module URL Rewriting
Cách tốt nhất để thực hiện một giải pháp URL Rewriting là tạo ra một module dễ cấu hình và có thể tái sử dụng, vì vậy quyết định sáng suốt nhất là tạo ra một HTTPModule và thực hiện nó như là một đơn vị (assembly) riêng lẻ. Để tạo đơn vị (assembly) này dễ sử dụng đến mức có thể, cần phải hiểu rõ việc cấu hình cơ chế viết lại (rewrite) và đặc tả được các quy luật trong tập tin web.config.
Trong quá trình phát triển, cần phải có khả năng tắt, mở module URL Rewriting (ví dụ trong trường hợp gặp lỗi khó sửa, đó có thể là nguyên nhân do các quy luật viết lại được mô tả không đúng).
<rewriteModule>
<rewriteOn>true</rewriteOn> <rewriteRules>
<rule source="(\d+)/(\d+)/(\d+)/"
destination="Posts.aspx?Year=$1&Month=$2&Day=$3"/>
<rule source="(.*)/Default.aspx" destination="Default.aspx? Folder=$1"/>
</rewriteRules> </rewriteModule>
Hình 3.14 - Module URL Rewriting có chức năng tắt/mở module thông qua thuộc tính rewriteOn
Điều này có nghĩa là các yều cầu đến server dạng: http://localhost/Web/2006/12/10/ được kết nối lại đến trang Post.aspx với các tham số truy vấn dạng chuỗi. (trong trường hợp này là trang http://localhost/Web/Post.aspx?Year=2006&Month=12&Day=3). Tập tin web.config dạng tâp tin dạng cú pháp XML vì vậy ký tự & trong giá trị chuỗi thuộc tính bị cấm. Trong trường này, phải sử dụng mã & thay cho ký tự trên.
Để sử dụng phần rewriteModule trong tập tin web.config, cần phải đăng ký (register) tên và điều khiển cho phần này. Cách làm đơn giản là thêm một phần configSections trong tập tin web.config.
<configSections>
<sectionGroup name="modulesSection">
<section name="rewriteModule" type="RewriteModule. RewriteModuleSectionHandler, RewriteModule"/>
</sectionGroup> </configSections>
Hình 3.15 - Phần configSections
Điều này có nghĩa là sẽ sử dụng phần sau đây dưới phần configSection:
<modulesSection> <rewriteModule> <rewriteOn>true</rewriteOn> <rewriteRules> <rule source="(\d+)/(\d+)/(\d+)/" destination="Post.aspx?Year=$1&Month=$2&Day=$3"/> <rule source="(.*)/Default.aspx" destination="Default.aspx?Folder=$1"/> </rewriteRules> </rewriteModule> </modulesSection>
Hình 3.16 - Phần modulesSection
Một điểm khác khi hướng về quá trình phát triển module rewriting là nên sử dụng những URL ảo với các tham số chuỗi truy vấn nếu có thể, ví dụ như đường dẫn sau đây: http://www.somebloghost.com/2006/12/10/?Sort=Desc&SortBy=Date. Trong đường dẫn này, hai tham số truy vấn là Sort và SortBy với các giá trị lần lượt là Desc và Date. Vì vậy, cần phát triển một giải pháp mới có thể dò tìm các tham số hợp quy cách thông qua các chuỗi truy vấn và thông qua URL ảo trong ứng dụng web.
Hình 3.17 - Quá trình ánh xạ một URL ảo thành một URL thực
Cấu hình Handling the configuration section
Để có thể đọc các tuỳ chọn cấu hình đặc tả trong tập tin web.config thì phải tạo một lớp thi hành giao diện IConfigurationSectionHandler. Điều này được mô tả như hình sau:
using System; using System.Collections.Generic; using System.Text; using System.Configuration;
using System.Web; using System.Xml; namespace RewriteModule
{
public class RewriteModuleSectionHandler : IConfigurationSectionHandler {
private XmlNode _XmlSection; private string _RewriteBase; private bool _RewriteOn; public XmlNode XmlSection {
get { return _XmlSection; } }
public string RewriteBase {
get { return _RewriteBase; } }
public bool RewriteOn {
get { return _RewriteOn; } }
public object Create(object parent, object configContext, System.Xml.XmlNode section)
{
// set base path for rewriting module to // application root
_RewriteBase = HttpContext.Current.Request.ApplicationPath + "/";
// process configuration section // from web.config try { _XmlSection = section; _RewriteOn = Convert.ToBoolean( section.SelectSingleNode("rewriteOn").InnerText); }
catch (Exception ex) {
throw (new Exception("Error while processing RewriteModule configuration section.", ex)); } return this; } } } Hình 3.18 - Lớp code RewriteModuleSectionHandler
Lớp RewriteModuleSectionHandler được khởi tạo bằng cách gọi phương thức Create() với phần rewriteModule của tập tin web.config có quy cách là XmlNode. Phương thức SelectSingleNode của lớp XmlNode được sử dụng để trả về các giá trị cho các thiếp lập module.
Sử dụng các tham số từ URL được viết lại (rewritten)
Khi điều khiển các đường URL dạng như http://www.
somebloghost.com/Blogs/gaidar/?Sort=Asc (đường dẫn URL với các tham số chuỗi truy
vấn), việc phân biệt rõ ràng các tham số là một điều quan trọng khi xem xét tham số nào hợp quy cách thông qua một chuỗi truy vấn từ các tham số, tham số nào hợp quy cách như là các thư mục ảo. Sử dụng quy luật viết lại (rewriting) được mô tả như sau:
<rulesource="(.*)/Default.aspx" destination="Default.aspx?Folder=$1"/>
Hình 3.19 - Một quy luật viết lại (rewrite) kiểu thư mục
Với đoạn code trong hình trên, một đường dẫn có dạng: http://www. so.com/gaidar/?Folder=Blogs tương ứng với đường dẫn có dạng: http://www. so.com/Blogs/gaidar/
Để giải quyết được vấn đề này thì phải nên tạo một dạng bao bọc (wrapper) cho các tham số đường dẫn ảo. Điều này có thể là một tập hợp các phương thức tĩnh để truy cập các tập tham số hiện tại.
using System; using System.Collections.Generic;
using System.Text; using System.Collections.Specialized; using System.Web; namespace RewriteModule
{
public class RewriteContext {
// returns actual RewriteContext instance for current request public static RewriteContext Current
{
get {
// Look for RewriteContext instance in
// item then this means that rewrite module is turned off if(HttpContext.Current.Items.Contains("RewriteContextInfo")) return (RewriteContext)
HttpContext.Current.Items["RewriteContextInfo"]; else
return new RewriteContext(); }
}
public RewriteContext() {
_Params = new NameValueCollection(); _InitialUrl = String.Empty; }
public RewriteContext(NameValueCollection param, string url) {
_InitialUrl = url; _Params = new NameValueCollection(param);
}
private NameValueCollection _Params; public NameValueCollection Params {
get { return _Params; } set { _Params = value; } }
private string _InitialUrl; public string InitialUrl {
get { return _InitialUrl; }set { _InitialUrl = value; } }
}
}
Hình 3.20 Lớp RewriteContext
Có thể truy cập các tham số đường dẫn ảo (virtual path parameters) thông qua tập hợp RewriteContext.Current và chắc chắn các tham số này đã được đặc tả trong đường URL giống như là các thư mục ảo hoặc các tên trang, mà không phải là các tham số chuỗi truy vấn.