126
ĐẠI HỌC THĂNG LONG BỘ MÔN TIN HỌC CHUYÊN ĐỀ TỐT NGHIỆP TÌM HIỂU VÀ XÂY DỰNG ỨNG DỤNG WEB SIÊU THỊ TRỰC TUYẾN VỚI ASP.NET MVC SINH VIÊN : ĐẶNG TIẾN LỘC – A07138 GIÁO VIÊN HƢỚNG DẪN : ĐOÀN QUANG MINH HÀ NỘI 5/ 2010

CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

  • Upload
    hocit

  • View
    107

  • Download
    1

Embed Size (px)

DESCRIPTION

tai lieu ASP.NET

Citation preview

Page 1: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

ĐẠI HỌC THĂNG LONG

BỘ MÔN TIN HỌC

CHUYÊN ĐỀ TỐT NGHIỆP

TÌM HIỂU VÀ XÂY DỰNG ỨNG DỤNG

WEB SIÊU THỊ TRỰC TUYẾN

VỚI ASP.NET MVC

SINH VIÊN :

ĐẶNG TIẾN LỘC – A07138

GIÁO VIÊN HƢỚNG DẪN :

ĐOÀN QUANG MINH

HÀ NỘI 5/ 2010

Page 2: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

BẢNG KÝ HIỆU VIẾT TẮT

MVC Model View Controller Mô hình lập trình ba lớp Model, View, Controller

được sử dụng trong nhiều framework lập trình

web trong đó có ASP.NET MVC, ZEND, J2EE…

API Application

Programming Interface

Giao diện lập trình ứng dụng được sử dụng bởi

một ứng dụng qua đó cho phép nó tương tác với

ứng dụng khác

ACK ACKnowledgement Thừa nhận một trường xác thực trong gói tin

http.

URL Uniform Resource

Locator

Địa chỉ website

LINQ .NET Language

Intergrated Query

Ngôn ngữ truy vấn tích hợp với .NET

CDN Content Delivery

Network

Mạng phân phối nội dung

SMTP Simple Mail Transfer

Protocol

Giao thức gửi thư điện tử đơn giản

SSL Secure Socket Layer Tầng bảo mật Socket

IIS Internet Information

Server

Máy chủ thông tin mạng

EML Electronic Mail Thư điện tử (đuôi của tệp thư điện tử)

DOM Document Object

Model

định nghĩa tập các đối tượng chuẩn cho tất cả tài

liệu có cấu trúc

UI User Interface Giao diện người dùng

HTTP Hyper Text Transfer

Protocol

Giao thức truyền siêu văn bản

CPU Control Processing Unit Bộ điều khiển xử lí trong máy tính

Page 3: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

DLL Dynamic Link Library Thư viện liên kết động

ISAPI Internet Server API Giao diện lập trình người dùng của máy chủ

thông tin mạng

SP Store Procedure Thủ tục lưu trữ

SQL Structured Query

Language

Ngôn ngữ truy vấn có cấu trúc

CSDL Cơ sở dữ liệu Chứa các dữ liệu của hệ thống

OOP Object Oriented

Programming

Lập trình hướng đối tượng

TDD Test Driven

Development

Phát triển đi kèm với kiểm thử

Page 4: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

MỤC LỤC

i

MỤC LỤC

GIỚI THIỆU CHUNG ......................................................................................................... 1

CHƢƠNG 1: MỞ ĐẦU ........................................................................................................ 4 1.1. Tổng quan về ASP.NET MVC ............................................................................. 4

1.2. Tổng quan về ứng dụng thƣơng mại siêu thị trực tuyến ..................................... 4

2.1. Yêu cầu đặt ra cho kiến trúc hệ thống .................................................................. 5

2.2. Thiết kế kiến trúc hệ thống ................................................................................... 5

2.2.1. Thiết kế kiến trúc phân tầng .......................................................................... 6

2.2.2. Lựa chọn lƣu trữ dữ liệu và thiết kế tầng truy xuất dữ liệu .......................... 6

2.2.3. Thiết kế tầng logic nghiệp vụ ...................................................................... 10

2.2.4. Xây dựng vùng nhớ đệm, sử dụng mạng phân phối nội dung tăng hiệu năng

của hệ thống .............................................................................................................. 11

2.2.5. Tầng trình diễn ............................................................................................ 11

CHƢƠNG 2: TÌM HIỂU ASP.NET MVC VÀ LINQ ..................................................... 13 1.1. ASP.NET MVC là gì? ........................................................................................ 13

1.1.1. Mô hình MVC cơ bản ................................................................................. 13

1.1.2. Một vài đặc tính của ASP.NET MVC ......................................................... 14

1.2. Sự khác biệt so với Web Form ........................................................................... 14

1.3. Quá trình thực thi một ứng dụng nền web ASP.NET MVC .............................. 16

2.1. Linq to SQL là gì? .............................................................................................. 18

2.2. Mô hình hóa CSDL dùng Linq to SQL .............................................................. 18

2.3. Tìm hiểu lớp DataContext .................................................................................. 19

2.4. Các ví dụ Linq to SQL ....................................................................................... 20

2.5. Tổng kết .............................................................................................................. 22

CHƢƠNG 3: PHÂN TÍCH THIẾT KẾ ỨNG DỤNG ..................................................... 23 1.1. Thiết kế hệ thống ................................................................................................ 23

1.1.1. Các module của hệ thống ............................................................................ 23

1.1.2. Mối quan hệ giữa các module ..................................................................... 24

1.2. Đặc tả sơ lƣợc các module ................................................................................. 24

1.2.1. Module hồ sơ và thành viên ........................................................................ 24

1.2.2. Module lấy ý kiến khách hàng .................................................................... 24

1.2.3. Module thƣơng mại ..................................................................................... 24

1.2.4. Module gửi thƣ ............................................................................................ 24

1.2.5. Module diễn đàn.......................................................................................... 24

1.2.6. Module tìm kiếm siêu thị ............................................................................ 24

1.2.7. Module bài báo, tin tức, và blog ................................................................. 25

1.2.8. Module quốc tế hóa ..................................................................................... 25

1.2.9. Module kiểm thử ......................................................................................... 25

2.1. Tổng quan về module ......................................................................................... 26

2.2. Sơ đồ chức năng ................................................................................................. 26

2.3. Các bảng DL của module ................................................................................... 27

2.3.1. Tạo các bảng DL từ module hồ sơ, ngƣời dùng trong ASP.NET 2.0 ......... 27

2.3.2. Tạo bảng language ...................................................................................... 27

2.3. Cấu hình tệp web.config cho membership, role và profile: ............................... 28

2.4. Models ................................................................................................................ 29

2.4.1. Lớp UserInformation .................................................................................. 29

2.4.2. Lớp ProfileInformation ............................................................................... 30

2.5. Controllers .......................................................................................................... 30

2.6. Views .................................................................................................................. 31

2.7. Sử dụng Javascript .............................................................................................. 32

Page 5: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

2.8. Cấu hình định tuyến ........................................................................................... 33

3.1. Tổng quan về module ......................................................................................... 34

3.2. Sơ đồ chức năng ................................................................................................. 35

3.3. Tìm hiểu, sử dụng Paypal cho chức năng thanh toán ......................................... 35

3.3.1. Tạo tài khoản ảo cho mục đích kiểm thử .................................................... 35

3.3.2. Quá trình thanh toán với Paypal từ website thƣơng mại ............................. 36

3.4. Các bảng dữ liệu của module ............................................................................. 38

3.5. Lớp thiết lập cấu hình cho module thƣơng mại .................................................. 38

3.6. Model ................................................................................................................. 39

3.7. Controller ........................................................................................................... 40

3.8. View ................................................................................................................... 41

3.9. Sử dụng JavaScript ............................................................................................. 43

3.10. Cấu hình định tuyến ........................................................................................ 47

4.1. Tổng quan về module ......................................................................................... 50

4.2. Các vấn đề cần quan tâm khi xây dựng module: ................................................ 50

4.3. Sơ đồ chức năng ................................................................................................. 53

4.4. Các bảng dữ liệu ................................................................................................. 53

4.5. Thiết kế lớp cấu hình cho module ...................................................................... 54

4.6. Model ................................................................................................................. 54

4.7. Controller ........................................................................................................... 55

4.8. View ................................................................................................................... 55

4.9. Cấu hình định tuyến ........................................................................................... 56

5.1. Tổng quan về module ......................................................................................... 57

5.2. Sơ đồ chức năng ................................................................................................. 57

5.3. Các bảng dữ liệu ................................................................................................. 58

5.4. Thiết kế lớp cấu hình cho module ...................................................................... 59

5.5. Model ................................................................................................................. 59

5.6. Controller ........................................................................................................... 60

5.7. View ................................................................................................................... 61

5.8. Sử dụng javascript .............................................................................................. 61

5.9. Cấu hình định tuyến ........................................................................................... 66

6.1. Tổng quan về module ......................................................................................... 68

6.2. Sơ đồ chức năng ................................................................................................. 68

6.3. Các bảng dữ liệu ................................................................................................. 69

6.4. Xây dựng lớp ForumsElement cho thiết lập cấu hình module ........................... 69

6.5. Model ................................................................................................................. 69

6.6. Controller ........................................................................................................... 70

6.7. View ................................................................................................................... 71

6.8. Sử dụng javascript .............................................................................................. 72

6.9. Cấu hình định tuyến ........................................................................................... 76

6.10. Cấu hình trong tệp web.config........................................................................ 78

7.1. Tổng quan về module ......................................................................................... 79

7.2. Sơ đồ chức năng ................................................................................................. 79

7.3. Các bảng dữ liệu ................................................................................................. 80

7.4. Xây dựng lớp ArticleElement cho thiết lập cấu hình của module ..................... 80

7.5. Model ................................................................................................................. 81

7.6. Controller ........................................................................................................... 82

7.7. View ................................................................................................................... 83

7.8. Sử dụng javascript .............................................................................................. 84

7.9. Cấu hình định tuyến ........................................................................................... 90

8.1. Tổng quan về module ......................................................................................... 94

Page 6: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

8.2. Xây dựng module ............................................................................................... 94

8.2.1. Các Service hỗ trợ quốc tế hóa trong Framework của Microsoft ............... 94

8.2.2. Xây dựng các tệp tài nguyên ....................................................................... 95

8.2.3. Controller của module ................................................................................. 97

8.2.4. View tƣơng ứng của module ....................................................................... 97

9.1. Tổng quan về module ......................................................................................... 99

9.2. Code cho module ................................................................................................ 99

CHƢƠNG 4: SỬ DỤNG WEB FORMS TRONG ỨNG DỤNG ASP.NET MVC ...... 101 1.1. Các lí do cho sự kết hợp giữa 2 công nghệ ...................................................... 101

1.2. Tại sao có thể thực hiện đƣợc sự kết hợp này .................................................. 101

1.3. Các bƣớc để kết hợp các trang WebForms vào ứng dụng ASP.NET MVC .... 101

2.1. Tổng quan về module ....................................................................................... 102

2.2. Sơ đồ chức năng ............................................................................................... 102

2.3. Phân tích cách xây dựng chức năng ................................................................. 102

2.4. Bảng CSDL ...................................................................................................... 103

2.5. Các lớp hỗ trợ trong module ............................................................................ 104

2.6. View ................................................................................................................. 107

2.7. Thêm định tuyến cho các trang view của module ............................................ 107

2.8. Vấn đề bảo mật ................................................................................................. 108

CHƢƠNG 5: TRIỂN KHAI ỨNG DỤNG VÀ HƢỚNG PHÁT TRIỂN .................... 110 1.1. Các bƣớc triển khai .......................................................................................... 110

1.2. Triển khai Global Store Site ............................................................................. 110

1.3. Cấu hình IIS 7.0 cho Framework MVC sử dụng Microsoft Web Platform

Installer ....................................................................................................................... 111

1.4. Thêm Global Store site vào IIS 7.0 .................................................................. 113

2.1. Hỗ trợ tìm kiếm sản phẩm mở rộng ................................................................. 115

2.2. Mở rộng chức năng tìm kiếm cửa hàng gần nhất ............................................. 115

2.3. Xây dựng module báo cáo tình hình bán hàng của siêu thị kết xuất ra các tệp

định dạng Execel, Pdf ................................................................................................. 115

KẾT LUẬN ....................................................................................................................... 116

TÀI LIỆU THAM KHẢO ................................................................................................ 117

DANH MỤC HÌNH ẢNH ................................................................................................ 118

Page 7: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

1

GIỚI THIỆU CHUNG

Trong chuyên đề tốt nghiệp này tôi thực hiện việc tìm hiểu công nghệ ASP.NET

MVC, mô hình thương mại điện tử trực tuyến của các chuỗi siêu thị lớn trên thế

giới như http://www.bestbuy.com, http://www.walmart.com/ qua đó xây dựng hệ

thống thương mại trực tuyến trên nền tảng công nghệ ASP.NET MVC và ASP.NET

gồm các module như sau:

Module thành viên và hồ sơ

- Đăng kí tài khoản.

- Đăng nhập, đăng xuất.

- Quản lí hồ sơ.

- Quản lí vai trò người dùng trong đó có xem toàn bộ các vai trò có trong hệ

thống, xóa, và tạo vai trò.

- Quản lí người dùng trong đó có xem danh sách những người dùng có trong

hệ thống, tìm kiếm người dùng theo tên và email, xóa người dùng, và sửa

đổi thông tin người dùng.

Moudle thương mại

- Duyệt toàn bộ các gian hàng trong siêu thị.

- Xem một gian hàng theo danh sách các sản phẩm có trong gian hàng, chọn

và đưa một sản phẩm vào giỏ hàng.

- Xem chi tiết một sản phẩm trong gian hàng, đưa sản phẩm vào giỏ hàng.

- Quản lí các gian hàng trong đó có xem toàn bộ các gian hàng trong hệ

thống, chỉnh sửa, và xóa một gian hàng, tạo gian hàng mới.

- Quản lí các sản phẩm trong đó có xem danh sách các sản phẩm trong hệ

thống, chỉnh sửa thông tin sản phẩm, xóa sản phẩm, tạo sản phẩm mới.

- Quản lí các chọn lựa cách giao hàng trong đó có xem danh sách các cách

giao hàng, xóa, thêm cách thức giao hàng.

- Quản lí các đơn đặt hàng trong đó có xem danh sách các đơn hàng có

trong hệ thống, xem chi tiết từng đơn hàng.

Mudule tin tức – bài báo – blog.

- Xem danh sách các bài báo.

- Xem các bài báo theo đầu mục.

Page 8: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

2

- Xem chi tiết một bài báo, viết lời bình và đánh giá bài báo.

- Quản lí các đầu mục trong đó có chỉnh sửa đầu mục, xóa đầu mục, và tạo

đầu mục.

- Quản lí các bài báo trong đó có xem các bài báo có trong hệ thống, chỉnh

sửa, xóa, tạo bài báo mới.

- Quản lí các nhận xét bài báo trong đó có xem toàn bộ các nhận xét có trong

hệ thống, chỉnh sửa, xóa một nhận xét.

Module trưng cầu ý kiến khách hàng

- Xem các trưng cầu, cho ý kiến.

- Quản lí các trưng cầu trong đó có chuyển trưng cầu sang trạng thái đã lấy

đủ ý kiến, hiện hành, chỉnh sửa trưng cầu, xóa trưng cầu, tạo trưng cầu

mới.

Module gửi thư từ hệ thống

- Xem toàn bộ các thư đã gửi đi từ hệ thống, xóa các thư đã gửi.

- Tạo và gửi thư.

Module định vị cửa hàng siêu thị gần nhất

- Tìm các siêu thị trong khoảng cách nhất định đối với một địa chỉ cho trước.

- Tìm đường đi tới 1 siêu thị từ địa chỉ đó.

- Thêm vị trí siêu thị mới vào hệ thống.

Module diễn đàn

- Duyệt các diễn đàn.

- Xem các bài thảo luận, tham gia thảo luận, xác nhận thích hay không thích

bài thảo luận, tạo bài thảo luận.

- Quản lí các diễn đàn trong đó có chỉnh sửa, xóa diễn đàn.

- Quản lí các bài thảo luận trong đó có chấp thuận cho bài thảo luận được

hiển thị, đóng luồng thảo luận khi nó quá dài, xóa bài thảo luận.

Module quốc tế hóa

- Hiển thị các thông tin địa phương ứng với địa phương mà người dùng đăng

kí trong hồ sơ của họ như tiền dùng ở địa phương, thời gian, cách viết con

số của địa phương,…

Page 9: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

3

Module kiểm thử

- Kiểm thử phần bài báo, blog.

- Kiểm thử phần gửi thư.

Page 10: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

4

CHƢƠNG 1: MỞ ĐẦU

1. LÍ DO THỰC HIỆN ĐỀ TÀI

1.1. Tổng quan về ASP.NET MVC

Không phải tự nhiên mà rất nhiều framework xây dựng ứng dụng nền tảng web

phổ biến nhất hiện nay kế thừa các nguyên tắc thiết kế của MVC như Django,

Ruby on Rails, CakePHP, Struts, … Sự thành công của việc kế thừa kiểu mẫu lập

trình này cuối cùng cũng đã khiến Microsoft quyết định đưa các nguyên tắc đó vào

sử dụng trong .NET Framework và rồi hình thành nên ASP.NET MVC đầu năm

2007 với phiên bản lúc đó là 1.0.

Công nghệ lập trình ASP.NET MVC này tuy rằng không phải là công nghệp lập

trình ứng dụng nền tảng web tốt nhất hiện nay của Microsoft cũng không phải

dùng để thay thế công nghệ ASP.NET song nó có những ưu điểm nhất định, được

sử dụng khá phổ biến và đang tiếp tục được hỗ trợ phát triển của Micorosoft.

Chính vì những lí do này mà nó đáng được tìm hiểu để từ đó sử dụng một cách

hiệu quả.

1.2. Tổng quan về ứng dụng thƣơng mại siêu thị trực tuyến

Việc mua bán kinh doanh hiện nay đang ngày càng trở nên dễ dàng hơn với sự hỗ

trợ của công nghệ thông tin. Hiện nay có một số lượng rất lớn các website thương

mại đã được xây dựng và sử dụng. Việc này giúp đa dạng hóa các phương thức

bán hàng và vì vậy hàng hóa được tiêu thụ dễ dàng hơn. Có rất nhiều ích lợi từ

việc kinh doanh trực tuyến có thể thấy được như:

Đối với khách hàng:

Mua hàng ở bất kể đâu miễn là họ có máy tính kết nối mạng.

Nhanh chóng tìm kiếm được mặt hàng cần mua chỉ qua vài click chuột.

Không phải đối mặt với nhân viên bán hàng.

Đối với doanh nghiệp:

Có thêm được một kênh quảng bá sản phẩm hiệu quả mà chi phí thấp.

Nắm bắt được thông tin phong phú về thị trường và đối tác.

Thiết lập được mối quan hệ tốt với khách hàng và đối tác.

Đa dạng hóa các kênh bán hàng của doanh nghiệp.

….

Hệ thống siêu thị trực tuyến là một ví dụ điển hình về thương mại điện tử nó có

đầy đủ các module mà một hệ thống thương mại điện tử cần có. Trong chuyên đề

tốt nghiệp của mình tôi sẽ xây dựng hệ thống bán hàng trực tuyến dựa trên công

nghệ ASP.NET MVC là chủ yếu.

Page 11: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

5

2. SƠ LƢỢC VỀ YÊU CẦU KIẾN TRÚC CỦA HỆ THỐNG

2.1. Yêu cầu đặt ra cho kiến trúc hệ thống

Xây dựng nên hệ thống siêu thị trực tuyến cấu thành từ các module riêng biệt

đồng thời quản lí nội dung động của hệ thống như bài báo,diễn đàn, phiếu điều tra

và gửi thư từ hệ thống. Ta cần giải quyết các vấn đề chung đặt ra với mỗi module

đó là:

Tách biệt mã lệnh truy cập CSDL với mã lệnh logic nghiệp vụ và mã lệnh

cho giao diện để hệ thống có thể dễ dàng bảo trì và mở rộng. Đây là kiểu

thiết kế phân tầng cho hệ thống.

Cô lập kiến trúc truy cập CSDL để từ đó có thể hỗ trợ việc lưu trữ với công

cụ lưu trữ CSDL quan hệ khác nhau như SQL, MySQL, Oracle,.. mà không

phải thực hiện thay đổi nào với tầng đối tượng nghiệp vụ. Ngược lại việc

thay đổi tầng trình diễn hay tầng đối tượng nghiệp vụ cũng không làm thay

đổi các tầng còn lại. Việc làm này tạo ra sự cách ly giữa các tầng của hệ

thống.

Thiết kế kiến trúc đối tượng nghiệp vụ lấy từ tầng truy cập CSDL theo kiểu

hướng đối tượng bằng cách ánh xạ cơ sở dữ liệu quan hệ vào các lớp

hướng đối tượng.

Xây dựng bộ nhớ đệm lưu các đối tượng nghiệp vụ. Điều này giúp làm giảm

áp lực xử lí yêu cầu người dùng với CPU của máy chủ, nguồn CSDL, băng

thông mạng và như vậy làm tăng hiệu năng chung của hệ thống.

Tạo tệp cấu hình cho từng module để có thể dễ dàng thay đổi chúng.

2.2. Thiết kế kiến trúc hệ thống

Với các dự án ASP.NET truyền thống ta sẽ không bao giờ thực sự tách riêng được

phần giao diện người dùng với logic ứng dụng bởi vì .NET cung cấp sẵn các điều

khiển phía máy chủ mà ta thường sử dụng bằng cách kéo thả vào các trang cung

cấp giao diện ví dụ như GridView. Các control kiểu này giúp chúng ta thực hiện

khá nhiều việc tuy nhiên lại thường làm cho mã lệnh xử lí logic của ứng dụng lẫn

vào với mã lệnh giao diện. Một ví dụ thường thấy đó là việc tạo ra logic để sắp xếp

các GridView hay lọc dữ liệu ứng với một sự kiện nhấn chuột. Khi sử dụng những

control như thế ta luôn cần có các tệp mã lệnh để xử lí logic đằng sau các trang

giao diện.

Chúng ta có thể tự tạo trọn vẹn một ứng dụng có tính module tuy nhiên điều này

dẫn tới việc ta phải tự xây dựng framework cho ứng dụng của mình.

Với sự ra đời của framework asp.net mvc thì mọi thứ đã thay đổi hẳn không còn

các tệp mã lệnh xử lí logic đằng sau các trang giao diện giúp tách biệt hoàn toàn

giữa giao diện với logic nghiệp vụ của ứng dụng và như vậy ứng dụng nền tảng

web của ta đã được xây dựng theo kiến trúc phân tầng.

Page 12: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

6

2.2.1. Thiết kế kiến trúc phân tầng

Với ứng dụng siêu thị trực tuyến ta sẽ chia thành các tầng như sau:

Tầng lưu trữ dữ liệu: Nơi lưu trữ CSDL. CSDL của hệ thống siêu thị trực tuyến là

CSDL quan hệ.

Tầng truy cập CSDL (Data Access Layer – DAL): Mã lệnh để lấy dữ liệu, xử lí dữ

liệu thô được lưu trong tầng lưu trữ DL. Nhiệm vụ của tầng này là đưa ra các truy

xuất CSDL theo logic nghiệp vụ và có tính trực quan hơn cho ứng dụng. Che dấu

các chi tiết thâm nhập CSDL ở mức thấp tăng tính an toàn cho CSDL của hệ

thống.

Tầng nghiệp vụ (Business Logic Layer – BLL): Mã lệnh ở tầng này sẽ thực hiện

các nguyên tắc nghiệp vụ, tạo các đối tượng cụ thể thuộc miền nghiệp vụ nhằm

thỏa mãn các yêu cầu của ứng dụng.

Tầng Logic ứng dụng (Application Logic Layer): Mã lệnh thuộc tầng này sẽ xử lí

các tương tác giữa tầng trình diễn với tầng logic nghiệp vụ.

Tầng trình diễn (Presentation Layer – PL) : Là các đoạn mã lệnh tạo nên những gì

mà người dùng thấy ở trên trình duyệt. Nó có thể là các dữ liệu đã được định

dạng, thực đơn duyệt hệ thống, …

Hình 1.1 – Kiến trúc ứng dụng

2.2.2. Lựa chọn lƣu trữ dữ liệu và thiết kế tầng truy xuất dữ liệu

Ở ứng dụng này ta lựa chọn lưu trữ CSDL với máy chủ SQL 2008 tuy nhiên trong

thực tế có thể khách hàng lại muốn sử dụng máy chủ Oracle hay IBM DB2 … vì

nhiều lí do như họ muốn tích hợp ứng dụng của bạn vào một dự án lớn hơn mà dự

án này lại dùng máy chủ Oracle để lưu trữ dữ liệu nên tầng truy xuất dữ liệu cần

được thiết kế sao cho đủ linh hoạt để việc thay đổi diễn ra dễ dàng, nhanh chóng.

Tầng truy xất dữ liệu là mã lệnh thực hiện truy vấn CSDL để lấy dữ liệu, cập nhật,

chèn, hay xóa dữ liệu. Đây là mã lệnh gần với CSDL nhất, sử dụng tất cả những gì

có trong CSDL từ giản đồ các bảng,các thủ tục lưu trữ, các hàm … cho đến các

Page 13: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

7

trường. Mã lệnh truy xuất tới CSDL cụ thể phải được tách biệt với mã lệnh các

trang web vì các lí do như:

Người viết mã lệnh cho phần giao diện và người viết mã lệnh cho phần truy

cập CSDL có thể không phải là một. Với những ứng dụng nền tảng web cỡ

vừa và lớn thì thường có nhiều lập trình viên tham gia xây dựng. Người xây

dựng giao diện sẽ hầu như không quan tâm tới CSDL. Tuy nhiên họ vẫn

cung cấp giao diện hiển thị thông tin từ CSDL bởi lẽ tất cả các chi tiết hiển

thị đã được gói gọn trong các đối tượng riêng biệt cung cấp việc truy vấn

CSDL ở mức cao, trừu tượng hơn.

Một vài truy vấn CSDL sẽ được sử dụng ở một số các trang của ứng dụng.

Nếu như ta đặt trực tiếp truy vấn vào các trang này mà sau đó ta muốn thay

đổi một câu lệnh truy vấn như thay đổi cách thức sắp xếp, hoặc thay đổi các

trường dữ liệu ta sẽ phải xem lại toàn bộ mã lệnh xem nơi nào sử dụng

chúng và thực hiện thay đổi. Nếu như ta đưa toàn bộ mã lệnh truy cập

CSDL vào một vài lớp trong tầng truy xuất CSDL ta sẽ chỉ phải thay đổi các

tệp này mà không cần quan tâm tới các trang chứa mã lệnh giao diện.

Mã lệnh truy vấn CSDL mà đặt cùng với mã lệnh giao diện sẽ làm ta khó

khăn trong việc thay đổi sang CSDL quan hệ khác.

Với công nghệ asp.net mvc việc tách biệt tầng truy xuất CSDL là gần như bắt

buộc. Tất cả các đối tượng liên quan tới tầng truy xuất CSDL nên được đặt trong

thư mục tên là Models.

Để xử lí việc hỗ trợ lưu trữ dữ liệu linh động với các máy chủ CSDL khác nhau ta

sẽ sử dụng kiểu mẫu thiết kế Provider Model cụ thể là thay vì việc viết trực tiếp các

lớp truy cập CSDL đầu tiên ta sẽ viết lớp trừu tượng và giao diện công khai của

các lớp đó và cả các phương thức hỗ trợ nếu cần. Mã lệnh thực sự dùng truy vấn

CSDL sẽ nằm ở lớp kế thừa trực tiếp từ lớp trừu tượng và lớp này sẽ đưa ra các

mã lệnh cụ thể cho các phương thức trong giao tiếp của lớp trừu tượng. Lớp trừu

tượng được gọi là lớp cung cấp và đây là lí do vì sao Micorsoft gọi kiểu mẫu thiết

kế này là Provider Model.

Rõ ràng khi thay đổi máy chủ CSDL ta chỉ việc thay đổi CSDL, thay đổi các lớp thứ

2 này là xong. Hơn thế nữa với lớp trừu tượng ta biết rõ được phải xây dựng lớp

thứ 2 như thế nào và chúng ta không hề phải thay đổi các module khác ngoại trừ

module tầng truy cập CSDL. Trong trường hợp buộc phải thêm các lớp cung cấp

mới thì ta có thể biến các lớp cung cấp cũ thành virtual để từ đó cho phép các lớp

provider mới có các hàm quá tải các hàm của các provider cũ.

Hình dưới đây minh họa mối quan hệ giữa các tầng giao diện, logic nghiệp vụ, truy

cập CSDL và lưu trữ CSDL với nhiều công cụ lưu trữ khác nhau.

Page 14: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

8

Hình 1.2 – Mối quan hệ giữa các tầng giao diện, logic nghiệp vụ, truy cập

CSDL và lưu trữ CSDL

Sử dụng LINQ ở tầng truy cập CSDL (DAL)

Với .NET Framework 3.5 chúng ta được cung cấp một tính năng mới là LINQ

(Language Intergrated Query). LINQ được thiết kế để cung cấp cách thực hiện truy

vấn trên bất kể kiểu collection nào trong .NET Framework bao gồm mảng,

dictionaries, lists, XML, và các CSDL,…

LINQ có những tính năng đáng để xem xét dù ta có thể đơn giản sử dụng kiểu

typed data sets hay các thực thể ta tạo ra để thực hiện việc xây dựng tầng truy vấn

CSDL theo mong muốn như:

Sử dụng các cấu trúc truy vấn giống với SQL trong mã lệnh .NET hay xem

đoạn code này:

SQL

select c.*

from Customer as c

Page 15: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

9

LINQ

var customers = from c in dataContext.Customers

select c;

2 câu lệnh trên thực thi cùng một nhiệm vụ là truy vấn thông tin khách hàng

từ bảng Customers, tuy nhiên trong cách truy vấn sử dụng LINQ thì dữ liệu

được chuyển thành kiểu collection, gọi là Iqueryable<Customer>, giúp ta có

thể sử dụng vòng lặp chuẩn foreach. Trong C# ta thấy có từ khóa mới là

var. Đây là kiểu dữ liệu nạc danh (kiểu dữ liệu này chỉ được xác định khi

biên dịch – trình biên dịch sẽ biết nó có kiểu gì khi biên dịch và thay từ khóa

var với tên kiểu đúng của nó)

Với LINQ có thể sử dụng kiểu dữ liệu an toàn và các truy vấn đa dạng hơn.

Hãy xem câu lệnh truy vấn xem mỗi khách hàng trả bao nhiêu cho các đơn

đặt hàng của họ trong năm 2008 bằng SQL và LINQ:

SQL

select c.CustomerId, c.Name as CustomerName, sum(o.TotalPaid) as TotalPaid

from Customer as c inner join Orders as o

on c.CustomerId = o.CustomerId where o.OrderDate >= ‘1/1/2008’

and o.OrderDate <= ‘12/31/2008’ group by c.CustomerId, c.Name

LINQ

var customers = from c in dataContext.Customers join o in dataContext.Orders on c.CustomerId

equals o.CustomerId where c.OrderDate >= new Date(2008, 1, 1)

&& c.OrderDate <= new Date(2008, 12, 31) group o by new { c.CustomerId, c.Name } into g select new {

CustomerId = c.CustomerId, CustomerName = c.Name, TotalPaid = g.Sum(o => o.TotalPaid) };

Trong ví dụ với LINQ thì trường OrderDate có kiểu là System.DateTime. Vì

vậy nếu ta so sánh nó với dữ liệu kiểu chuỗi, hay bất kể một đối tượng nào

không phải kiểu DateTime thì trình biên dịch sẽ báo lỗi và cho biết chính xác

vị trí lỗi xảy ra đây là một ích lợi khi sử dụng LINQ so với việc sử dụng SQL.

Ví dụ dưới đâu sẽ cho thấy với LINQ ta có các truy vấn tiện ích hơn so với

SQL ví dụ như lấy một oder có ID = 2, lấy OderInformation của oder đó thay

đổi ngày thêm vào rồi lưu oder này lại vào CSDL.

var order = (from o in dataContext.Orders where o.OrderId == 2

Page 16: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

10

select o).FirstOrDefault(); foreach(var orderInformation in order.OrderInformation)

orderInformation.DateAdded = DateTime.Now; dataContext.SubmitChanges();

LINQ-to-SQL : Để LINQ có thể được sử dụng ta cần phải khởi tạo model

tương ứng. Việc tạo model này hoàn toàn có thể thực hiện bằng cách kéo

thả các bảng cũng như thủ tục lưu vào giao diện thiết kế của tệp thiết kế

các lớp LINQ to SQL. Các lớp thực thể sẽ được tạo tự động. Việc tạo các

lớp thực thể với LINQ to SQL như vậy giúp xây dựng ứng dụng nhanh

chóng tuy nhiên lại là hạn chế vì cách tạo các lớp thực thể này chỉ có máy

chủ SQL của Microsoft hỗ trợ.

2.2.3. Thiết kế tầng logic nghiệp vụ

Tầng truy cập CSDL được xây dựng với LINQ-to-SQL trả về các tập hợp của các lớp thực thể chứa các trường của dữ liệu từ bảng dư liệu. Tuy nhiên dữ liệu trả về của tầng này vẫn là dữ liệu thô dù chúng được chứa trong các lớp bởi vì chúng được sinh tự động. Chúng chỉ là nơi chứa các dữ liệu có định kiểu mạnh được sử dụng để truyền dữ liệu giữa các tầng lưu trữ dữ liệu và tầng logic nghiệp vụ. Tầng nghiệp vụ logic sử dụng các dữ liệu này chuyển chúng tới tầng giao diện người dùng. Ở tầng này có thể có thêm kiểm định logic, xây dựng các biểu thức tính toán dựa trên các thuộc tính, chuyển một số thuộc tính thành kiểu private hay read-only thêm các phương thức tĩnh, thực thể để xử lí việc xóa, chỉnh sửa, truy xuất dữ liệu. Việc tạo các dữ liệu hướng đối tượng, định kiểu mạnh tạo ra sự trừu tượng hóa mạnh mẽ cô lập tầng lưu trữ CSDL cung cấp cho lập trình viên phát triển giao diện tập hợp các lớp đơn giản, xong hiệu quả khi sử dụng. Với asp.net mvc framework thì tầng logic nghiệp vụ nằm gọn trong các điều khiển và các lớp điều khiển bắt buộc phải được đặt trong thư mục Controllers giúp tách hẳn tệp code behind ra khỏi tệp mã lệnh giao diện. Các lớp này sử dụng các kiểu tập hợp xử lí dữ liệu ứng dụng thông qua các kiểu tập hợp này rồi trả lại view tương ứng. Với việc tạo tầng logic nghiệp vụ ở thư mục controllers trong ứng dụng .net mvc thì ta có được một số ích lợi như:

Tạo được các kiểm định bộ phận cho ứng dụng bởi lẽ tất cả các logic nghiệp vụ được đặt trong thư mục Controllers hoặc các thực thể mà ta tạo ra. Không có các trình điều khiển phía máy chủ và như vậy việc kiểm định bộ phận không bị lỗi.

Bảo mật dễ dàng hơn bởi lẽ tất cả các xử lí được đặt trong các lớp điều khiển ta không còn phải tách biệt các trang cần có cấp phép cao hơn và đưa ra lệnh chứng thực cấp phép với thư mục chứa các trang này.

Ta có thể trả về nhiều giao diện từ một phương thức hành động trong controller.

Với vấn đề bảo mật ta chỉ cần xử lí đơn giản như trong đoạn code sau: [Authorize (Roles = ‚Admin‛)] public ActionResult EditContent (int id, ..) {

Page 17: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

11

//logic dùng chỉnh sửa nội dung return View(); }

2.2.4. Xây dựng vùng nhớ đệm, sử dụng mạng phân phối nội dung tăng

hiệu năng của hệ thống

Với những ứng dụng nền tảng web có những dữ liệu ít thay đổi và thường được yêu cầu bởi nhiều người dùng và trong hệ thống siêu thị trực tuyến các dữ liệu như vậy có thể kể tới như danh sách các đầu mục bài báo, đầu mục sản phẩm và các sản phẩm… Để có thể tăng hiệu ứng cho hệ thống với những dữ liệu kiểu này ta có thể tạo vùng nhớ đệm cho chúng và giữ vùng nhớ đệm này ở bộ nhớ trong những khoảng thời gian xác định. Asp.net framework cũng khá mạnh trong việc giúp chúng ta xây dựng, quản lí vùng nhớ đệm ở trong các lớp điều khiển. Hãy xem một ví dụ sau cho thấy việc tạo vùng nhớ đệm và duy trì nó trong 60 giây [OutputCache (Duration = 60)] public ActionResult SomeControllerMethod() { //logic nghiệp vụ } Trong trường hợp hệ thống được truy cập bởi một lượng lớn người dùng mỗi ngày vài ngàn đến vài chục ngàn ta có thể tính tới việc sử dụng các mạng phân phối nội dung (CDN) đây là mạng phát tán của các máy chủ giúp ta giải quyết vấn đề quá tải truy cập nội dung của hệ thống, giúp người dùng truy cập nội dung hệ thống nhanh hơn. Các mạng này thực hiện công việc phôn phối nội dung thông qua mạng của các máy chủ quản lí tên miền (DNS) hướng yêu cầu của người dùng tới một máy chủ có sẵn nội dung người dùng cần và gần người dùng đó nhất. Nội dung cần phân phối có thể là các file ảnh, javascript, css, tài liệu, phim ảnh, âm thanh … với hệ thống siêu thị trực tuyến này thì các tệp nội dung được đặt trong thư mục Content việc đưa tất cả các file nội dung vào thư mục này sẽ rất phù hợp với cơ chế làm việc của CDN ở chỗ để CDN hoạt động ta cần phải cài phần mềm tương ứng vào máy chủ web chứa hệ thống và cấu hình để phần mềm này biết cụ thể vị trí của nội dung cần phân phối việc đưa nội dung cần phân phối vào một thư mục sẽ dễ dàng cho việc cấu hình và quá trình tìm kiếm của phần mềm này. Về mặt giá cả thì giải pháp sử dụng CDN sẽ rẻ hơn nhiều so với việc thuê đường truyền có băng thông lớn hơn.

2.2.5. Tầng trình diễn

Tầng trình diễn tương ứng với các trang giao diện duy chỉ có điều là không có các tệp mã lệnh đằng sau mỗi trang đó. Theo công nghệ ASP.NET MVC thì các tệp mã lệnh đó được thay thế bằng những lớp điều khiển. Tuy nhiên còn các điều khiển phía máy chủ (được cung cấp bởi Microsoft, hoặc các hãng thứ 3) vẫn thường được sử dụng trong các trang chứa mã lệnh giao diện của asp.net trước kia thì

Page 18: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

12

sao? Trên thực tế những control kiểu này không còn cần thiết trong các trang đó nữa. ASP.NET MVC framework đem lại rất nhiều lựa chọn thay thế cho các điều khiển phía máy chủ của công nghệ ASP.NET đó mà trong hệ thống siêu thị trực tuyến sử dụng. Framework này có một tập các phương thức mở rộng hỗ trợ HTML giúp tự động tạo và gắn kết dữ liệu của phần lớn các điều khiển phía máy chủ mà ta vẫn sử dụng với các trang chứa mã lệnh ASP.NET. Ví dụ như tạo textbox và tiêu đề của textbox sau được ánh xạ bởi ViewData. <label for =‛title‛> Title </label><br/> <%= Html.Textbox(‚Title‛, ViewData.Model.Title)%> Khi đoạn code trên được chuyển tới trình duyệt thì nó được chuyển thành đoạn code HTML tương ứng sau:

<label for =‛title‛> Title </label><br/> <input id = ‚Title‛ name = ‚Title‛ type = ‚text‛ vale=‛Chief Technology Officer‛/> Đoạn code này đơn giản chỉ có thẻ input mà hoàn toàn không có liên quan tới thuộc tính runat. Đối với trình duyệt input này được viết hoàn toàn bằng HTML điều này giúp tối ưu hóa khả năng tìm kiếm hệ thống của các hệ thống tìm kiếm như google hay bing giúp các khách hàng chưa biết tới hệ thống có thể tìm đến hệ thống thông qua cỗ máy tìm kiếm dễn dàng hơn. Ở tầng này của hệ thống siêu thị trực tuyến có sử dụng javascript ở để xử lí các sự kiện không đồng bộ phía người dùng. Cụ thể ta sẽ sử dụng JQuery – đây là javascript framework ổn định, ra đời cách đây vài năm, có các tài liệu hỗ trợ đầy đủ, dễ sử dụng.

Page 19: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

13

CHƢƠNG 2: TÌM HIỂU ASP.NET MVC VÀ LINQ

1. TỔNG QUAN VỀ ASP.NET MVC

1.1. ASP.NET MVC là gì?

1.1.1. Mô hình MVC cơ bản

MVC viết tắt của các chữ cái đầu của Models, Views, Controllers. MVC chia giao

diện UI thành 3 phần tương ứng: đầu vào của controller là các điều khiển thông

qua HTTP request, model chứa các miền logic, view là những gì được sinh ra trả

về cho trình duyệt.

Hình 2.1 – Mô hình MVC cơ bản

Lợi ích của việc dùng phương pháp MVC là sự phân tách rõ ràng giữa models,

views, controllers bên trong ứng dụng. Cấu trúc sạch giúp cho việc kiểm tra lỗi ứng

dụng trở nên dễ dàng hơn.

Page 20: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

14

1.1.2. Một vài đặc tính của ASP.NET MVC

Tách rõ ràng các mối liên quan giữa các module, mở ra khả năng kiểm thử theo mô hình TDD. Có thể kiểm thử bộ phận trong ứng dụng mà không cần phải chạy lớp điều khiển cùng với tiến trình của ASP.NET và có thể dùng bất kỳ một framework kiểm thử nào như NUnit, MBUnit, MS Test, v.v…

Mọi thứ trong MVC được thiết kế cho phép dễ dàng thay thế/tùy biến ( ví dụ: có thể lựa chọn sử dụng engine view riêng, engine controller riêng, routing policy, parameter serialization, v.v…).

Có một bộ ánh xạ URL mạnh cho phép xây dựng ứng dụng với những URL sạch, các URL không cần phần mở rộng như aspx ( ví dụ: có thể ánh xạ địa chỉ /Products/Edit/4 để thực hiện hành động “Edit” của lớp điều khiển ProductControllers hoặc ánh xạ địa chỉ /Blog/SomeTopic để thực hiện hành động “Display Topic” của lớp điều khiển BlogEngineController ) và được thiết kế để hỗ trợ kiểu mẫu đặt tên url qua đó hỗ trợ tối ưu hóa của bộ máy tìm kiếm.

ASP.NET MVC Framework cũng hỗ trợ những tệp của ứng dụng ASP.NET như .ASPX .ASCX và .Master, đánh dấu các tập tin này như một “view template” ( có thể dễ dàng dùng các tính năng của ASP.NET như lồng các trang Master, <%= %> snippets, mô tả các điều khiển phía máy chủ, template, data-binding, localization, v.v… ). Tuy nhiên sẽ không còn cơ chế postback và interactive back server và thay vào đó là interactive end-user tới một lớp Controller ( không còn viewstate, page lifecycle )

ASP.NET MVC Framework hỗ trợ đầy đủ các tính năng bảo mật của ASP.NET như xác thực theo forms/windows, URL authorization, membership/roles, output và data caching, session/profile state, configuration system, provider architecture v.v…

1.2. Sự khác biệt so với Web Form

ASP.NET WebForm sử dụng ViewState để quản lý, các trang ASP.NET đều có lifecycle,cơ chế postback và dùng các điều khiển, các sự kiện để thực thi hành động trên giao diện khi có sự tương tác với người dùng nên nếu trang ASP.NET có quá nhiều điều khiển thì việc xử lý yêu cầu người dùng sẽ chậm. ASP.NET MVC Framework chia ra thành 3 phần: Models, Views, Controllers. Mọi tương tác của người dùng với Views sẽ thực hiện hành động trong Controllers, không còn postback, không còn lifecycle hay các sự kiện nữa.

Việc kiểm tra, gỡ lỗi với ASP.NET đều phải chạy tất cả các tiến trình của ASP.NET và mọi sự thay đổi ID của bất kỳ điều khiển nào cũng ảnh hưởng đến ứng dụng. Đối với ASP.NET MVC Framework thì việc có thể sử dụng các unit test có thể kiểm định khá dễ dàng hoạt động của các controller.

Page 21: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

15

Tính năng ASP.NET 2.0 ASP.NET MVC

Kiến trúc chương trình Kiến trúc mô hình trang

giao diện Bussiness

Database

Kiến trúc sử dụng việc

phân chia chương trình

thành Controllers, Models,

Views

Cú pháp chương trình Sử dụng cú pháp của

webform. Tất cả các sự

kiện và controls đều do

máy chủ quản lí

Các sự kiện được điều

khiển bởi Controllers, các

controls không do máy

chủ quản lí

Truy cập dữ liệu Sử dụng hầu hết các công

cụ truy cập dữ liệu trong

ứng dụng

Có thể dùng LINQ to SQL

class để tạo mô hình truy

cập đối tượng

Gỡ rối Gỡ rối chương trình phải

thực hiện tất cả bao gồm

các lớp truy cập dữ liệu,sự

hiển thị, các điều khiển

Gỡ rối có thể sử dụng các

unit test để kiểm tra các

phương thức trong

controller

Tốc độ phân tải Tốc độ phân tải chậm trong

khi trang có quá nhiều điều

khiển vì khi đó ViewState

quá lớn

Phân tải nhanh hơn do

không phải sử dụng

ViewState để quản lý các

điều khiển trong trang

Tương tác với javascript Tương tác với javascript

khó khăn vì các điều khiển

bị quản lí bởi máy chủ

Tương tác với javascript

dễ dàng vì các đối tượng

không do máy chủ quản lí

dẫn tới điều khiển không

khó khăn

URL address Cấu trúc địa chỉ URL có

dạng

<filename>.aspx?&<các

tham số>

Cấu trúc địa chỉ URL rành

mạch, dễ hiểu theo dạng

Controllers /Action/ Id

Page 22: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

16

1.3. Quá trình thực thi một ứng dụng nền web ASP.NET MVC

Một yêu cầu gửi tới ứng dụng nền tảng web viết bằng ASP.NET MVC đầu tiên sẽ đi qua đối tượng UrlRoutingModule, đây là một module HTTP. Module này sẽ phân tích yêu cầu và thực thi việc chọn lựa định tuyến. Nó sẽ chọn đối tượng route đầu tiên thích hợp với yêu cầu hiện thời.(Đối tượng route mở rộng lớp RouteBase và là một thể hiện cụ thể của lớp Route) Nếu không có định tuyến nào thích hợp đối tượng UrlRoutingModule sẽ không thực hiện việc định tuyến mà trả yêu cầu đó về cho IIS hay ASP.NET xử lí. (Xem hình 2.2) Từ đối tượng Route được chọn, đối tượng UrlRoutingModule lấy đối tượng IRouteHandler tương ứng với đối tượng Route. Cụ thể trong một ứng dụng ASP.NET MVC thì IRouteHandler là một thể hiện của MvcRouteHandler. Thể hiện này sẽ tạo ra một đối tượng IHttpHandler và truyền nó tới đối tượng IHttpContext. Theo mặc định,thể hiện IHttpContext của MVC là đối tượng MvcHandler. Đối tượng này sẽ chọn ra controller xử lí yêu cầu gửi từ ứng dụng. Module nói trên và IIS là các điểm đầu vào đối với ASP.NET MVC framework. Chúng thực hiện những việc sau:

Chọn ra một controller tương ứng xử lí yêu cầu từ ứng dụng MVC.

Có được một thể hiện cụ thể của controller đó.

Gọi phương thức Execute của controller này.

Bảng liệt kê các giai đoạn thực thi của một dự án nền Web ASP.NET MVC

Giai đoạn Chi tiết

Nhận yêu cầu

đầu tiên từ

ứng dụng

Trong file Global.asax, các đối tượng Route được thêm vào đối

tượng RouteTable

Thực thi định

tuyến

Module UrlRoutingTable sử dụng đối tượng Route đầu tiên

thích hợp trong tập RouteTable tạo đối tượng RouteData. Đối

tượng này sau đó lại tạo ra đối tượng RequestContext

(IHttpContext).

Tạo trình xử lí

yêu cầu từ

MVC

Đối tượng MvcRouteHandler tạo ra một thể hiện của lớp

MvcHandler và truyền vào nó thể hiện RequestContext

Tạo controller Đối tượng MvcHandler sử dụng thể hiện của RequestContext

để xách định đối tượng IcontrollerFactory qua đó tạo ra thể

hiện controller

Page 23: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

17

Thực thi

controller

Thể hiện MvcHandler gọi phương thức Execute controller.

Gọi phương

thức hành

động từ

controller

tương ứng

Hầu hết các controllers đều kế thừa từ lớp Controller cơ bản.

Đối với các controller như thế đối tượng

ControllerActionInvoker đi kèm với controller đó sẽ xác định

phương thức action của lớp controller đó để gọi, và rồi gọi

phương thức đó.

Thực thi kết

quả

Một phương thức hành động cụ thể nhận dữ liệu từ người dùng

sẽ chuẩn bị dữ liệu trả về thích hợp. Những kiểu dữ liệu trả về

được xây dựng sẵn có thể được trả về gồm có: ViewResult

(Thể hiện một View và là dữ liệu thường được trả về nhất),

RedirectToRouteResult, RedirectResult….

Hình 2.2 – Mô hình xử lí yêu cầu từ ứng dụng ASP.NET MVC

Page 24: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

18

2. LINQ TO SQL

2.1. Linq to SQL là gì?

LINQ to SQL là một phiên bản hiện thực hóa của O/RM (object relational mapping) có bên trong .NET Framework bản “Orcas” (nay là .NET 3.5), nó cho phép bạn mô hình hóa một cơ sở dữ liệu dùng các lớp .NET. Sau đó bạn có thể truy vấn cơ sở dữ liệu dùng LINQ, cũng như cập nhật/thêm/xóa dữ liệu từ đó. LINQ to SQL hỗ trợ đầy đủ transaction, view và các thủ tục lưu. Nó cũng cung cấp

một cách dễ dàng để thêm khả năng kiểm tra tính hợp lệ của dữ liệu và các quy

tắc vào trong mô hình dữ liệu của bạn.

2.2. Mô hình hóa CSDL dùng Linq to SQL

Visual Studio “Orcas” đã tích hợp thêm một trình thiết kế LINQ to SQL như một công cụ dễ dàng cho việc mô hình hóa một cách trực quan các CSDL dùng LINQ to SQL. Ta sẽ xem xét cách dùng trình thiết kế này. Bằng cách dùng trình thiết kế LINQ to SQL, ta tạo một mô hình cho CSDL mẫu

“Northwind” giống như dưới đây:

Hình 2.3 – Mô hình LINQ to SQL

Page 25: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

19

Mô hình LINQ to SQL ở trên định nghĩa bốn lớp thực thể: Product, Category, Order và OrderDetail. Các thuộc tính của mỗi lớp ánh xạ vào các cột của bảng tương ứng trong CSDL. Mỗi thể hiện của một lớp biểu diễn một dòng trong bảng dữ liệu. Các mũi tên giữa bốn lớp thực thể trên biểu diễn quan hệ giữa các thực thể khác nhau, chúng được tạo ra dựa trên các mối quan hệ khóa chính/khóa ngoại trong CSDL. Hướng của mũi tên chỉ ra mối quan hệ là một – một hay một – nhiều. Các thuộc tính tương ứng sẽ được thêm vào các lớp thực thể trong các trường hợp này. Lấy ví dụ, lớp Category ở trên có một mối quan hệ một nhiều với lớp Product, điều này có nghĩa nó sẽ có một thuộc tính “Categories” là một tập hợp các đối tượng Product trong Category này. Lớp Product cũng sẽ có một thuộc tính “Category” chỉ đến đối tượng ”Category” chứa Product này bên trong. Bảng các phương thức bên tay phải bên trong trình thiết kế LINQ to SQL ở trên

chứa một danh sách các thủ tục lưu để tương tác với mô hình dữ liệu của chúng

ta. Trong ví dụ trên tôi đã thêm một thủ tục có tên “GetProductsByCategory”. Nó

nhận vào một categoryID và trả về một chuỗi các Product. Chúng ta sẽ xem bằng

cách nào có thể gọi được thủ tục này trong một đoạn code bên dưới.

2.3. Tìm hiểu lớp DataContext

Khi ta bấm nút “Save” bên trong màn hình thiết kế LINQ to SQL, Visual Studio sẽ lưu các lớp .NET biểu diễn các thực thể và quan hệ bên trong CSDL mà chúng ta vừa mô hình hóa. Cứ mỗi một tệp LINQ to SQL chúng ta thêm vào solution, một lớp DataContext sẽ được tạo ra, nó sẽ được dùng khi cần truy vấn hay cập nhật lại các thay đổi. Lớp DataContext được tạo sẽ có các thuộc tính để biểu diễn mỗi bảng được mô hình hóa từ CSDL, cũng như các phương thức cho mỗi thủ tục lưu mà chúng ta đã thêm vào. Lấy ví dụ, dưới đây là lớp NorthwindDataContext được sinh ra dựa trên mô hình

chúng ta tạo ra ở trên:

Page 26: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

20

Hình 2.4 – Mô hình NorthwindDataContext

2.4. Các ví dụ Linq to SQL

Lấy sản phẩm từ CSDL:

Đoạn lệnh dưới đây dùng cú pháp LINQ để lấy về một chuỗi IEnumerable các đối

tượng Product. Các sản phẩm lấy ra phải thuộc phân loại “Beverages”:

Hình 2.5 – Hình minh họa lấy sản phẩm từ CSDL với LINQ

Cập nhật một sản phẩm trong CSDL:

Đoạn lệnh dưới đây cho thấy cách lấy một sản phẩm,cập nhật giá tiền và lưu lại

vào CSDL.

Page 27: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

21

Hình 2.6 – Hình minh họa cập nhật sản phẩm từ CSDL với LINQ

Chèn thêm một phân loại mới và 2 sản phẩm vào CSDL:

Đoạn mã dưới đây biểu diễn cách tạo một phân loại mới, và tạo hai sản phẩm mới,

đưa chúng vào trong phân loại đã tạo rồi đưa vào CSDL.

Chú ý rằng ta không cần phải quản lý các mối quan hệ khóa chính/khóa ngoại,

thay vào đó, chỉ đơn giản thêm các đối tượng Product vào tập hợp Products của

đối tượng category, và rồi thêm đối tượng category vào tập hợp Categories của

DataContext, LINQ to SQL sẽ tự thiết lập các giá trị khóa chính/khóa ngoại một

cách thích hợp.

Hình 2.7 – Chèn sản phẩm mới vào CSDL

Xóa các sản phẩm:

Đoạn mã sau sẽ biểu diễn cách xóa tất cả các sản phẩm Toy khỏi CSDL:

Hình 2.8 – Xóa một sản phẩm

Gọi một thủ tục:

Đoạn mã dưới đây biểu diễn cách lấy các thực thể Product mà không dùng cú

pháp của LINQ, mà gọi đến thủ tục “GetProductsByCategory” chúng ta đã thêm

Page 28: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

22

vào trước đây. Nhớ rằng một khi đã lấy về kết quả, ta có thể cập nhật/xóa và sau

đó gọi db.SubmitChanges() để cập nhật các thay đổi trở lại CSDL.

Hình 2.9 – Gọi một thủ tục

Lấy các sản phẩm và phân trang:

Đoạn mã dưới đây biểu diễn cách phân trang trên máy chủ như một phần của câu

truy vấn LINQ. Bằng cách dùng các toán tử Skip() và Take(), chúng ta sẽ chỉ trả về

10 dòng từ CSDL – bắt đầu từ dòng 200.

Hình 2.10 – Lấy các sản phẩm và phân trang

2.5. Tổng kết

LINQ to SQL cung cấp một cách hay, rõ ràng để mô hình hóa lớp dữ liệu trong

ứng dụng của bạn. Một khi đã định nghĩa mô hình dữ liệu, bạn có thể dễ dàng

thực hiện các câu truy vấn cũng như cập nhật, xóa, sửa dữ liệu một cách hiệu

quả.

Page 29: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

23

CHƢƠNG 3: PHÂN TÍCH THIẾT KẾ ỨNG DỤNG

1. ĐẶC TẢ CÁC CHỨC NĂNG HỆ THỐNG

1.1. Thiết kế hệ thống

Tham khảo và mô phỏng lại hầu hết các chức năng của các hệ thống như

http://www.bestbuy.com/site/index.jsp,http://www.walmart.com/

Trong quá trình thiết kế hệ thống ta sẽ lần lượt làm rõ các module của hệ thống và

mối quan hệ giữa các module. Quá trình thiết kế của hầu hết các module có các

bước như nhau bao gồm tổng quan về module, sơ đồ chức năng,bảng DL của

module, lớp thực thể dữ liệu,bảng lớp điều khiển,bảng liệt kê giao diện người dùng

của module, thiết lập bảng định tuyến, thiết lập cấu hình cần thiết.

1.1.1. Các module của hệ thống

Hệ thống siêu thị bán hàng trực tuyến về cơ bản hỗ trợ người dùng duyệt,mua và

thanh toán hàng. Bên cạnh đó người dùng với vai trò quản trị hệ thống, nhân viên

siêu thị có thể quản lí được hàng hóa (xem, thêm,xóa,sửa), quản lí thông tin đặt

mua, thanh toán, vận chuyển hàng. Ngoài ra hệ thống còn có thêm một số module

như module diễn đàn, module bài báo tin tức, module lấy ý kiến khách hàng,

module gửi thư từ hệ thống, module định vị siêu thị, module quốc tế hóa.

Hình 3.1 – Các module của hệ thống siêu thị trực tuyến

Hệ thống Global Store

Module quản lí thành viên và

hồ sơ

Module lấy ý kiến khách hàng

Module thƣơng mại

Module gửi thƣ

Module diễn đàn

Module tìm kiếm siêu thị

Module địa phƣơng hóa

Module kiểm thử

Module bài báo, tin tức, blog

Page 30: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

24

1.1.2. Mối quan hệ giữa các module

Tất cả các module của hệ thống là độc lập với nhau ngoại trừ việc chúng sử dụng

module thành viên và hồ sơ cho việc xác thực vai trò người dùng và cho phép sử

dụng chức năng cụ thể của một module ứng với vai trò đó.

Việc tách biệt các module như vậy giúp hệ thống linh hoạt hơn khi nâng cấp, hay

có sửa đổi.

1.2. Đặc tả sơ lƣợc các module

1.2.1. Module hồ sơ và thành viên

Module này với người dùng là khách hàng thì họ có thể sử dụng để tạo tài khoản, đăng nhập, đăng xuất,quản lí hồ sơ còn đối với người quản trị hệ thống thì họ còn dùng vào việc quản lí vai trò người dùng, xóa, tạo vai trò, quản lí người dùng.

1.2.2. Module lấy ý kiến khách hàng

Với module lấy ý kiến khách hàng với vai trò admin người dùng có thể tạo các câu hỏi để lấy ý kiến khách hàng qua đó nắm bắt được các thông tin cần thiết để phát triển việc kinh doanh của công ty, hay phát triển hệ thống để phục vụ khách hàng tốt hơn. Người dùng là khách hàng có thể đóng góp ý kiến của mình để được phục vụ tốt hơn.

1.2.3. Module thƣơng mại

Sử dụng module thương mại người dùng là khách hàng có thể xem, chọn mua sản phẩm, thanh toán qua paypal. Đối với người dùng có vai trò là quản lí siêu thị (store keeper) – người quản lí sẽ quản lí gian hàng mà họ tạo ra như quản lí sản phẩm, quản lí đơn đặt hàng..

1.2.4. Module gửi thƣ

Khi sử dụng module này người dùng là khách hàng có thể đăng kí nhận thư của hệ thống thông qua mục nhận thư trong hồ sơ. Còn với người dùng có vai trò admin thì họ còn có thể tạo thư và gửi thư tới toàn bộ các thành viên có đăng kí nhận thư từ hệ thống.

1.2.5. Module diễn đàn

Người dùng nạc danh có thể duyệt xem bài bình luận trong các diễn đàn, tuy nhiên để gửi bài hay bình luận họ phải đăng nhập vào hệ thống. Chức năng quản lí diễn đàn, quản lí các bài thỏa luận dành cho người dùng có vai trò là editor. (biên tập)

1.2.6. Module tìm kiếm siêu thị

Người dùng có thể sử dụng module này để tìm kiếm các siêu thị gần nơi mình ở theo khoảng cách và tìm đường đi đến một siêu thị nào đó.

Page 31: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

25

Với người dùng có vai trò quản trị thì còn có thêm chức năng thêm vị trí siêu thị mới vào hệ thống.

1.2.7. Module bài báo, tin tức, và blog

Người dùng sử dụng module này có thể xem toàn bộ các bài báo, xem theo đầu mục, xem chi tiết bài báo, viết lời bình luận và cho điểm bài báo. Người dùng với vai trò là biên tập có thêm các chức năng như quản lí các đầu mục báo, tạo đầu mục mới, xóa đầu mục đang có trong hệ thống. Quản lí các bài báo trong đó có xem các bài báo, chỉnh sửa, xóa, tạo bài báo mới.

1.2.8. Module quốc tế hóa

Module này cho người dùng biết thông tin địa phương của người dùng qua thông tin ở hồ sơ đăng kí như thời gian, tiền dùng tại địa phương (chẳng hạn như ở Mĩ là USD, ở Việt nam là VND)

1.2.9. Module kiểm thử

Ở module này với phạm vi thực hiện chuyên đề tốt nghiệp tôi chỉ thực hiện kiểm

thử đơn giản với hai module khác trong hệ thống là module bài báo, tin tức, blog

và module gửi thư.

Page 32: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

26

uc Membership and Profile Management

Administrator

(from Actors)

Login

Register Account

Logout

Manage Profile

Create Role

Manage User

Delete User

Change Password

Delete Role

Forgot Password

Edit User

Anonymous User

(from Actors)

Registered User

(from Actors)

Manage Role

«include»

«include»

«include»

«include»

2. MODULE HỒ SƠ NGƢỜI DÙNG VÀ THÀNH VIÊN

2.1. Tổng quan về module

Module sẽ sử dụng hệ thống quản lí thành viên xây dựng sẵn của ASP.NET 2.0 cung cấp bởi Microsoft cho phép người dùng thực hiện các chức năng như đăng kí tài khoản, đăng nhập, thay đổi mật khẩu, lấy lại mật khẩu, nhập thông tin hồ sơ, cho phép nhà quản trị hệ thống đăng nhập vào hệ thống, quản lí quyền, quản lí người dùng (trong đó có xem toàn bộ người dùng trong hệ thống, tìm người dùng và xóa người dùng, thay đổi vai trò người dùng... Trước khi lưu trữ mật khẩu người dùng vào CSDL để bảo mật tất cả các mật khẩu sẽ được thay đổi thông qua hàm băm bằng cách thiết lập cách lưu trữ mật khẩu sử dụng hàm băm ở tệp web.config trong mục. Ghi chú: Module này được sử dụng bởi hầu hết các module khác như module cộng đồng, module tin tức bài báo, hay module đánh giá và cho điểm các luồng thảo luận trong diễn đàn,..

2.2. Sơ đồ chức năng

Hình 3.2 – Sơ đồ tổng quan chức năng của module theo mô hình UC

Page 33: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

27

2.3. Các bảng DL của module

2.3.1. Tạo các bảng DL từ module hồ sơ, ngƣời dùng trong ASP.NET 2.0

Tạo mới CSDL GlobalStore với SQL Server Management Studio, rồi chạy tệp aspnet_regsql trong thư mục C:\Windows\Microsoft.NET\Framework\v2.0.50727 để tạo các bảng dành cho module mà ASP.NET phiên bản 2.0 đã cung cấp sẵn như hình vẽ. Đây thực chất là việc chạy một đoạn script để tạo CSDL cho việc quản lí hồ sơ và người dùng

Hình 3.3 – Tạo CSDL cho module hồ sơ và người dùng

2.3.2. Tạo bảng language

Bảng language để lưu thông tin ngôn ngữ trong hồ sơ người dùng gồm 2 cột LanguageID (mã ngôn ngữ ), và LanguageName (tên ngôn ngữ) như sau:

Hình 3.4 Bảng Langugage

Page 34: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

28

2.3. Cấu hình tệp web.config cho membership, role và profile:

Để có thể sử dụng module quản lí hồ sơ và thành viên dựng sẵn trong ASP.NET 2.0 ta còn phải thiết lập cấu hình cho module trong thẻ <system.web> của tệp web.config : Mục membership: <membership> <providers> <clear/>

<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider,System.Web, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

connectionStringName="GlobalStoreConnectionString" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="GlobalStore" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"

passwordStrengthRegularExpression=""/> </providers> </membership>

Qua nội dung phần config có thể thấy việc cấu hình để sử dụng module Membership của ASP.NET 2.0 ASPNET. Trong đó mật khẩu trước khi lưu xuống CSDL được thay đổi thông qua hàm băm passwordFormat="Hashed",…

Mục Role: <roleManager enabled="true"> <providers> <clear/>

<add connectionStringName="GlobalStoreConnectionString" applicationName="GlobalStore"name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider,System.Web,

Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </providers> </roleManager> Mục Profile:

ASP.NET cung cấp một cơ chế có sẵn để quản lí hồ sơ người dùng. Ta chỉ cần khai báo các thông tin cần thiết lưu trong hồ sơ. Khi ứng dụng chạy thông tin thuộc tính của hồ sơ sẽ được thêm vào lớp Page.

Page 35: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

29

<profile> <properties> <add name="Subscription" type="String"/> <add name="Language" type="String"/> <add name="ShoppingCart" type="GlobalStore.Models.ShoppingCart" serializeAs="Binary" allowAnonymous="true"/> <group name="PersonalInformation"> <add name="FirstName" type="String"/> <add name="LastName" type="String"/> <add name="Gender" type="String"/> <add name="BirthDate" type="DateTime"/> <add name="Occupation" type="String"/> <add name="Website" type="String"/> </group> <group name="ContactInformation"> <add name="Street" type="String"/> <add name="City" type="String"/> <add name="State" type="String"/> <add name="ZipCode" type="String"/> <add name="Country" type="String"/> </group> </properties> </profile>

2.4. Models

2.4.1. Lớp UserInformation

Hệ thống có một số trang mà người dùng sử dụng liên quan với việc đăng nhập và quản lí tài khoản của họ. Để truyền dữ liệu mà không phải tạo một số lượng lớn biến cho mỗi phương trức hành động ta tạo lớp UserInformation để truyền vào các phương thức hành động dưới dạng tham số đầu vào xem danh sách các phương thức hành động trong lớp controller của module.

Hình 3.5 Sơ đồ lớp UserInformation

Page 36: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

30

2.4.2. Lớp ProfileInformation

Lớp này được dùng để quản lí thông tin hồ sơ đồng thời hỗ trợ để tạo các chọn lựa dropdown trong phần điền thông tin trên trang quản lí hồ sơ như nghề nghiệp, nước hiện tại ở, ngôn ngữ, … Các thuộc tính của lớp tương ứng với các thuộc tính khai báo trong web.config và các phương thức tạo dropdown tương ứng cho phần quản lí hồ sơ người dùng gồm có dropdown cho các mục:

Country.

Gender.

Language.

Occupation.

Subscription.

Hình 3.6 Sơ đồ lớp ProfileInformation

2.5. Controllers

Tương ứng với các chức năng của module ta có các phương thức hành động cho controller của module này như sau:

Phương thức hành động Bảo mật

Các tham số

Logout ---- ----

Login ---- ----

Login_OnPost ---- string userName, string password, bool persistent, string returnUrl

Page 37: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

31

ForgotPassword ---- ----

ForgotPassword_OnPost ---- string userName, string secretAnswer

Register ---- ----

Register_OnPost ---- UserInformation userInformation

ChangePassword ---- string resetPassword

ChangePassword_OnPost ---- UserInformation userInformation

UserProfile ---- ----

UserProfile_OnPost ---- ProfileInformation profileInformation

GetErrorMessage ---- MembershipCreateStatus membershipCreateStatus

ManageUser Admin string searchType, string searchInput

DeleteUser Admin string id

ManageRole Admin ----

CreateRole Admin string newRole

DeleteRole Admin string id

EditUser Admin string id

EditUser_OnPost Admin string id, bool approved

2.6. Views

Module này tạo thành từ nhiều view trong đó có những views được sử dụng bởi người dùng không có vai trò quản trị và những views dành cho người dùng có vai trò quản trị. Dưới đây là thể hiện cụ thể của các views trong module này:

Liên kết tới trang đăng nhập được hiển thị trên cùng phía bên phải ngay sau mục tóm lược việc mua hàng – shopping summary của mỗi trang bất kể khi nào mà người dùng là nạc danh. Sau khi người dùng đăng nhập vào hệ thống thì liên kết này sẽ được ẩn đi thay vào đó là các chức năng mà người dùng đã đăng nhập có đó là đăng xuất, quản lí hồ sơ, và thay đổi mật khẩu. View đăng kí cho phép người dùng mới đăng kí tài khoản với hệ thống. Trong quá trình đăng kí người dùng mới sẽ tạo hồ sơ với các thông tin : FirstName (string), LastName (string), Gender (string), BirthDate (datetime), Occupation (sring), và website (string). Nhóm thông tin về địa chỉ trong hồ sơ có các thuộc tính phụ trợ sau: Street, PostCode, City, State và Country tất cả đều có kiểu string. Nhóm cuối cùng về Preferences có các thuộc tính Cultrure và Newsletter. View quên mật khẩu cho phép người dùng thay đổi mật khẩu bằng việc trả lời một câu hỏi bảo mật sau khi đã điền đúng tên người dùng vào ô người dùng. Sau khi trả lời đúng câu hỏi bảo mật lúc này người dùng sẽ được phép tạo mật khẩu mới và dùng tài khoản của mình với mật khẩu mới này. Trang quản lí hồ sơ người dùng sẽ chỉ truy cập được bởi người dùng. Nó cho phép người dùng thay đổi các thông tin trên hồ sơ mà họ thiết lập từ lúc họ tạo tài khoản. Các trang để quản lí người dùng dành cho người dùng có vai trò quản trị như view dành cho quản lí người dùng giúp nhà quản trị tìm kiếm người dùng hoặc bằng tên hoặc bằng địa chỉ, view dành cho việc chỉnh sửa thông tin liên quan tới người dùng

Page 38: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

32

sẽ hiển thị các chi tiết thêm về người dùng và cho phép nhà quản trị để hoặc không để tài khoản đó hoạt động, hay thay đổi cập nhật vai trò người dùng. Ngoài ra còn có view dành cho việc quản lí vai trò được sử dụng để tạo, xóa các vai trò trong hệ thống. Như vậy ta có các views của module này

Tên trang Đặc tả Đường dẫn ảo

ChangePassword.aspx Trang này dùng thay đổi mật khẩu của người dùng

user/changepassword/

EditUser.aspx Trang này cho phép thay đổi quyền người dùng, ngăn hoạt động của tài khoản

user/edituser/{id}

ForgotPassword.aspx Trong trường hợp người dùng quên mật khẩu

user/forgotpassword

Login.aspx Trang đăng nhập user /login

ManageRole.aspx Trang dành cho nhà quản trị tạo / xóa các vai trò áp dụng cho hệ thống

user/managerole

ManageUser.aspx Trang dành cho nhà quản trị xem danh sách người dùng, qua đó xóa người dùng

user/manageruser

Register.aspx Trang này cho phép người dùng nạc danh trở thành người dùng đã đăng kí bằng việc điền thông tin người dùng và đăng kí

user/register

UserProfile.aspx Trang hồ sơ dành cho người dùng thay đổi thông tin hồ sơ của mình

user/profile

Ghi chú: Đường dẫn ảo phục vụ cho việc xây dựng định tuyến cho bảng định tuyến

2.7. Sử dụng Javascript

Trong view của trang quản lí người dùng (ManageUser.aspx) việc xóa người dùng sẽ được xử lí bằng kĩ thuật Ajax với đoạn mã javascript trong tệp manage-user.js tệp này nằm trong thư mục /content/scripts/. Đoạn mã lệnh xóa người dùng sẽ được sử dụng để triệu gọi phương thức xóa người dùng DeleteUser trong UserController. Nội dung của đoạn lệnh: $(".delete-user-button").click(function() { var userId = $(this).attr("meta:id"); $.post( "/User/DeleteUser", { id: userId }, function(data) {

Page 39: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

33

$("#user-" + data.object.id).remove(); }, "json" ); return false; }); Tương tự vậy thì trong view của trang quản lí vai trò (ManageRole.aspx) chức năng xóa vai trò cũng được xử lí bằng kĩ thuật này với đoạn mã xóa nằm trong tệp manage-role.js thuộc thư mục scripts với đường dẫn /content/scripts/manage-role.js.

2.8. Cấu hình định tuyến

Sử dụng định tuyến mặc định routes.MapRoute( "Default", "{controller}/{action}", new { controller = (string)null, action = (string)null} );

Page 40: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

34

3. MODULE THƢƠNG MẠI

3.1. Tổng quan về module

Chuỗi các siêu thị của công ty Golbal Store Pte. đều có chung cấu trúc về các gian hàng như thiết bị âm thanh, đồ cho ô tô và thiết bị định vị, máy tính, điện thoại cố định và đồ văn phòng, âm nhạc, phim và sách truyện. Tuy nhiên có một số gian hàng trống tạo không gian mở cho người dùng thuê. Khách hàng khi thuê gian hàng trống phải đăng kí tài khoản, những khách hàng này có toàn quyền quản lí gian hàng của mình.

Khách hàng khi mua hàng trực tuyến với Global Store Pte họ có thể duyệt các gian hàng của siêu thị - xem danh sách các gian hàng. Danh sách các gian hàng sẽ có tên gian hàng và đặc tả về gian hàng. Khi khách hàng chọn xem một gian hàng hệ thống sẽ hiển thị danh sách các sản phầm có trong gian hàng đó. Danh sách các sản phẩm với mỗi sản phẩm sẽ có kèm theo thông tin vắn tắt về sản phẩm (tên sản phẩm, thông tin vắn tắt về sản phẩm, giá bán, giá bán giảm giá nếu có,số lượng sản phẩm còn trong cửa hàng) ,nút AddToCart cho phép người dùng chọn đưa sản phẩm vào giỏ hàng và một liên kết cho phép xem chi tiết sản phẩm, hình ảnh sản phẩm thường là nhỏ hơn so với hình ảnh trong mục xem chi tiết. Khi khách hàng chọn xem chi tiết sản phẩm thì sẽ được chuyển đến view dành cho xem chi tiết sản phẩm. Trên view này người dùng sẽ thấy được thông tin chi tiết sản phẩm như tên sản phẩm, số hiệu sản phẩm, hình ảnh sản phẩm to hơn nếu có, thông tin chi tiết về sản phẩm nếu có, giá bán, giá bán đã có khuyến mãi giảm giá nếu có, số lượng hàng có trong kho, ô chọn số lượng mua (khách hàng hoàn toàn có thể chọn mua với số lượng mong muốn vì siêu thị có thể điều động hàng), cuối cùng là nút AddtoCart. Nếu người dùng chọn mua sản phẩm thì sẽ thấy được một hoạt cảnh dạng hình ảnh sản phẩm bay vào giỏ hàng. Ở đây là sản phẩm sẽ bay vào vị trí có thông tin tóm tắt mua hàng các thông tin vắn tắt mua hàng sẽ được cập nhật đó là số tiền phải trả và số mặt hàng trong giỏ hàng Trong phần thông tin vắn tắt giỏ hàng cũng có liên kết check out đưa người dùng tới trang thông tin mua sắm chi tiết để qua đó người dùng có thể kiểm tra chi tiết hơn những gì mình đã mua. Khách hàng khi chọn liên kết check out ở mục thông tin mua sắm vắn tắt sẽ được chuyển tới view thông tin chi tiết mua sắm của khác hàng. Người dùng với vai trò quản lí siêu thị - Store Keeper khi đăng nhập vào hệ thống có thể quản lí gian hàng mà mình tạo ra như thêm mới các sản phẩm vào gian hàng, xóa sản phẩm của gian hàng, … Ngoài ra người dùng này còn có thể quản lí cách thức giao hàng như thêm và xóa cách thức giao hàng, quản lí các đơn đặt hàng như xem danh sách các đơn đặt hàng, xem chi tiết một đơn đặt hàng. Ghi chú: Với phần mua hàng thì không bắt buộc người dùng phải có tài khoản và đăng nhập vào hệ thống tránh trường hợp đôi khi người dùng không muốn mất thời gian đăng kí tài khoản

Page 41: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

35

uc ECommerce

View Shopping

Basket

User

(from Actors)

Add To Shopping

Basket

Remov e Item from

Shopping Basket

Checkout

View All Products in

Category

Login not required.

View Prouduct's

Detail

Edit Product

Manage Shipping

Add New Shipping

Option

Manage Oder

Manage Product

Delete Product

View Products by

Category

Create Prouct

View Oders detail

Delete Shipping

Option

Login required. User

can be either admin or

store worker

Manage DepartmentsRemov e Category

Edit Category

Paypal Use Cases

Filling Shipping

DetailsShipping Use Cases

Create Department

StoreKeeper

(from Actors)

«include»

«include»

«include»

«include»

«include»

«include»

«include»

«include»

«include»

«include»

3.2. Sơ đồ chức năng

Hình 3.7 Sơ đồ chức năng theo mô hình UC của module thương mại

3.3. Tìm hiểu, sử dụng Paypal cho chức năng thanh toán

Paypal có 3 loại tài khoản sử dụng tiền thật cho khách hàng, những người buôn

bán trực tuyến và các doanh nghiệp và 1 loại tài khoản dùng tiền ảo và dành cho

các nhà phát triển ứng dụng để thử nghiệm ứng dụng của mình. Ở đây ta quan

tâm tới loại hình tài khoản thứ tư : Sandbox Account vì ứng dụng chỉ ở dạng thử

nghiệm.

3.3.1. Tạo tài khoản ảo cho mục đích kiểm thử

Sandbox Account: Là tài khoản có thể ở dạng dùng cho doanh nghiệp, hoặc cho

người buôn bán trực tuyến hay cho cá nhân tuy nhiên lại chỉ được tạo ra và sử

dụng được trong môi trường thử nghiệm và dĩ nhiên chỉ dùng cho mục đích thử

Page 42: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

36

nghiệm mà thôi. Để kiểm nghiệm chỉ cần 2 tài khoản : 1 doanh nghiệp, 1 cá nhân

là đủ. Trước khi tạo 2 tài khoản này ta cần tạo tài khoản dành cho nhà phát triển

ứng dụng (Dùng Paypal cho website thương mại của mình) sau đó với tài khoản

này có thể tạo bao nhiêu tài khoản Sandbox tùy theo ý muốn. Tạo tài khoản dành

cho lập trình viên tại địa chỉ sau: https://developer.paypal.com/

Sau đó tạo 2 tài khoản Sandbox dành cho người mua và bán như hình vẽ sau

Hình 3.8 – Các tài khoản kiểm thử với sandbox Như vậy là ta đã có tài khoản để thực hiện các giao dịch ảo cho mục đích kiểm thử với website thương mại của mình.

3.3.2. Quá trình thanh toán với Paypal từ website thƣơng mại

Việc tích hợp thanh toán với Paypay cho hệ thống siêu thị trực tuyến là không quá phức tạp chỉ cần tạo ra một form HTML với các tham số tương ứng và điều hướng khách hàng từ website thương mại tới trang thanh toán với paypal. <form id="Paypal" name="Paypal" action="<%= GlobalStoreSection.Current.Commerce.PayPalServer %>" method="post"> <input type="hidden" name="cmd" value="_cart" /> <input type="hidden" name="upload" value="1" />

Page 43: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

37

<input type="hidden" name="business" value="<%= GlobalStoreSection.Current.Commerce.PayPalAccount %>" />

<input type="hidden" name="shipping" value="<%= ViewData.Model.ShippingPrice.ToString("N2") %>" /> <input type="hidden" name="amount" value="<%= ViewData.Model.Total.ToString("N2") %>" /> <% int count = 1; %> <% foreach(ShoppingCartItem shoppingCartItem in ViewData.Model) { %> <%=Html.Hidden("amount_" + count, shoppingCartItem.SalePrice.ToString("N2"))%> <%=Html.Hidden("item_name_" + count, shoppingCartItem.Title) %> <%=Html.Hidden("item_number_" + count, shoppingCartItem.Product.ProductID) %> <%=Html.Hidden("quantity_" + count, shoppingCartItem.Quantity) %> <%count++;%> <% } %> <button type="submit" id="paypal-checkout-button" value="PayPal" >Checkout</button> </form> Đây là bảng các liệt kê các tham số cần biết để xây dựng chức năng thanh toán

Thuộc tính Mô tả

cmd Cho biết ta đang sử dụng trang paypal ở chế độ gì. Ví dụ như khi cmd có giá trị _xclick tức là ta đang sử dụng Paypal ở chế độ thanh toán (Pay now). Như vậy trong hệ thống siêu thị trực tuyến này với chức năng checkout ta sẽ gán giá trị _xclick cho tham số cmd của checkout

upload Với giá trị là 1 cho tham số upload cho biết ta sử dụng giỏ hàng của hệ thống chứ không dùng giỏ hàng tích hợp của Paypal

business Địa chỉ thư xác định tài khoản business với Paypal của ta. Đây chính là tài khoản dùng để nhận thanh toán từ giao dịch của khách hàng. Với hệ thống tài khoản này là : [email protected]

item_name Đây là chuỗi mô tả đơn đặt hàng mà khách hàng sẽ thanh toán ví dụ như Oder #01

item_number Con số hay chuỗi số xác định cho một đơn đặt hàng

amount Số tiền mà khách hàng phải trả theo tiền của một nước nào đó được chỉ định bằng mã tiền (currency_code), định dạng tiền phải ở dạng như sau 33.88

quantity Tổng số sản phẩm đặt mua của một mặt hàng cụ thể

shipping Cước vận chuyển cũng được chỉ định theo tiền của nước được chỉ định ở tham số amount với cùng định dạng tiền như vậy

Page 44: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

38

3.4. Các bảng dữ liệu của module

Module thương mại có tất cả 5 bảng sản phẩm, bảng gian hàng (Deparments), bảng phương thức vận chuyển (ShippingMethods), bảng đơn đặt hàng (Oders), bảng các mặt hàng trong đơn đặt hàng (OderItems). Trong đó quan hệ giữa 2 bảng gian hàng và sản phẩm được thiết lập thông qua khóa ngoại là DepartmentID với updates và deletes là kiểu do đó khi xóa một gian hàng thì các sản phẩm có trong gian hàng cũng bị xóa. Tương tự thì có mối quan hệ giữa bảng đơn đặt hàng và bảng các mặt hàng trong đơn đặt hàng được thiết lập bởi khóa ngoại là OderID với updates và delete cũng là kiểu cascade.

Hình 3.9 Sơ đồ quan hệ các bảng dữ liệu trong module thương mại

3.5. Lớp thiết lập cấu hình cho module thƣơng mại

Lớp CommerceElement này dùng thiết lập các cấu hình thanh toán với Paypal được sử dụng để tạo các thuộc tính sau cho việc thanh toán

Thuộc tính Mô tả

Page 45: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

39

3.6. Model

Model của module này được chia làm 2 phần. Phần thứ 1 là các lớp thực thể LINQ-to-SQL được tạo tự động từ năm bảng DL trên.

Hình 3.10 – Sơ đồ các lớp thực thể LINQ-to-SQL của module

PayPalServer Đây chính là máy chủ Paypal mà khách hàng gửi yêu cầu tới đó có thể là máy chủ Sandbox dành cho thử nghiệm có địa chỉ (https://www.sandbox.paypal.com/cgi-bin/webscr) hoặc là máy chủ thực (https://www.paypal.com/cgi-bin/webscr)

PayPalAccount Đây là ID của PayPal của k hoặc là một địa chỉ thư điện tử tương ứng với tài khoản PayPal. Thư điện tử này cần được xác nhận lại với PayPal trước khi có thể dùng đại diện cho tài khoản đó

PayPalIdentityToken Đây là thẻ token được PayPal sử dụng để xác nhận một tài khoản nào đó. Nó có thể có được thông qua site của Paypal ở mục các tùy chọn trong tài khoản PayPal Vì lí do bảo mật thì token này không được gửi tới chủ tài khoản PayPal tuy nhiên khi chủ tài khoản sử dụng Token này thì nó sẽ xuất hiện ở phía dưới các nút bật tắt kiểu radio của phần truyền dữ liệu thanh toán trên trang tùy chọn phương thức thanh toán.

Page 46: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

40

Phần thứ 2 là các lớp thực thể ta xây dựng thêm hỗ trợ cho việc thực hiện một số chức năng của module ví dụ như phần chức năng với giỏ hàng. Lớp ShoppingCart được sử dụng bởi lớp trừu tượng Profile nhằm duy trì trạng thái giỏ hàng của một người dùng ngay cả khi người dùng này thoát khỏi hệ thống. Ngoài ra còn có lớp ShoppingCartItem và lớp tĩnh CommerceQueries chứa các phương thức mở rộng cho lớp Department, Products, và ShippingMethods

Hình 3.11 – Các lớp xây dựng thêm hỗ trợ cho module

3.7. Controller

Lớp controller xử lí toàn bộ các logic nghiệp vụ ứng với các use case của module và chứa các phương thức hành động như sau

Phương thức hành động Bảo mật Các tham số

Index ---- ----

ViewDepartment ---- int departmentId

ViewProduct ---- int productId

ViewShoppingCart ---- int? shippingMethod

AddShoppingCartItem ---- int productId, int? quantity

DeleteShoppingCartItem ---- int id

CompleteOder ---- string tx, decimal amt

ShoppingSummary ---- ----

ManageStore StoreKeeper ----

ManageDepartment StoreKeeper ----

CreateDepartment StoreKeeper ----

CreateDepartment_OnPost StoreKeeper string title, string imageUrl, string description, int? important

EditDepartment StoreKeeper int departmentId

EditDepartment_OnPost StoreKeeper int id, string title, string imageUrl, string description, int? important

DeleteDepartment StoreKeeper int id

ManageProduct StoreKeeper int id

CreateProduct StoreKeeper int id

CreateProduct_OnPost StoreKeeper int? departmentId, string title, string description, string sku, decimal? unit

Page 47: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

41

Price, int? discountPercentage, int? untisInStock, string smallImageUrl, string fullImageUrl

EditProduct StoreKeeper int productId

EditProduct_OnPost StoreKeeper int? departmentId, string title, string description, string sku, decimal? unit Price, int? discountPercentage, int? untisInStock, string smallImageUrl, string fullImageUrl

DeleteProduct StoreKeeper int id

ManageOders StoreKeeper int id

OderDetails StoreKeeper int id, string trackingId

ManageShipping StoreKeeper int id, string trackingId

CreateShipping StoreKeeper string title, decimal price

DeleteShipping StoreKeeper int id

3.8. View

Đây là một trong số các module có nhiều view nhất trong hệ thống. Gồm có các view dành cho người dùng với vai trò StoreKeeper và các view dành cho người dùng với các vai trò còn lại. Đây là danh sách các view của module

Tên trang Đặc tả Đường dẫn ảo Index.aspx Trang này hiển thị

các gian hàng và đóng vai trò là cổng dành cho việc duyệt các sản phẩm

store

ViewDepartment.aspx Trang này được dùng để hiển thị tất cả các sản phẩm trong một gian hàng

store/deparments/{deparmentId}

ViewProduct.aspx Trang này dùng hiển thị một sản phẩm

store/product/{productId}

ViewShoppingCart.aspx Trang này ngoài việc hiển thị chi tiết việc mua hàng của khách hàng thì nó còn cung cấp một số chức năng như xóa mặt hàng, thực hiện thanh toán với PayPal

store/cart

CompleteOder.aspx Trang này được sử dụng để trở về hệ thống khi khách hàng đã hoàn tất

store/oder/completed

Page 48: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

42

việc thanh toán qua PayPal

TransactionError.aspx Trong trường hợp có lỗi xảy ra trong quá trình giao dịch

Trang này không chứa đường dẫn ảo. Đường dẫn được định nghĩa bởi hệ thống sẽ được sử dụng để đưa ra thông báo lỗi

ManageStore.aspx Trang này hiển thị tất cả các mục trong module cần được quản lí bởi storekeeper

storekeeper/store

ManageDepartment.aspx Trang này hiển thị tất cả các gian hàng mà storekeeper tạo ra, cho phép storekeeper này có thể xóa, hay thực hiện những thay đổi

storekeeper/store/departments

CreateDeparment.aspx Trang này cho phép storekeeper tạo mới gian hàng và thay đổi lại thông tin về gian hàng

storekeeper/store/departments/create storekeeper/store/departments/edit/ {departmentId}

ManageProducts.aspx Trang này storekeeper dùng để thêm sản phẩm mới, thay đổi lại thông tin sản phẩm hiện có

storekeeper/store/products/create storekeeper/store/products/edit/ {productId}

MangeOder.aspx Trang này liệt kê tất cả các đơn đặt hàng của hệ thống

storekeeper/store/oders

OderDetail.aspx Trang này cho phép storekeeper xem chi tiết của đơn đặt hàng

storekeeper/store/oders/{oderId}

ManageShipping.aspx Trang này hiển thị tất cả các tùy chọn trong phương thức vận chuyển và cho phép storekeeper thêm mới hay xóa phương thức vận chuyển

storekeeper/store/shipping

Page 49: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

43

3.9. Sử dụng JavaScript

Mã lệnh javascript xử lí các sự kiện bất đồng bộ dành cho module này nằm trong các tệp commerece.js, manage-product.js, manage-deparment.js manage-department.js được sử dụng để đảm bảo các trường trong form quản lí gian hàng có được sinh ra như yêu cầu hay không: $("#title").focus(function () { ShowMessage(this, "Enter the title for your department."); }); $("#importance").focus(function() { ShowMessage(this, "(optional) Enter the order of importance that you want the departments shown in."); }); $("#imageUrl").focus(function() { ShowMessage(this, "The relative web path of an image you want to be shown with products in this department."); }); $("#description").focus(function() { ShowMessage(this, "Enter a short description of the department to display to your users."); }); function ValidateTitle() { return VerifyRequiredField("#title", "required"); } function ValidateImageUrl() { return VerifyRequiredField("#imageUrl", "required"); } function ValidateDescription() { return VerifyRequiredField("#description", "required"); } function ValidateDepartment() { var validTitle = ValidateTitle(); var validImage = ValidateImageUrl(); var validDescription = ValidateDescription(); return validTitle && validImage && validDescription; } $("form.department-create").validate(ValidateDepartment); Tương tự thì tệp manage-product được sử dụng để đảm bảo các trường thông tin trong form tạo sản phẩm được điền vào đúng theo yêu cầu .. /***************************************************************** Product ******************************************************************/

Page 50: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

44

$("#title").focus(function() { ShowMessage(this, "Enter your product name here."); }); $("#sku").focus(function() { ShowMessage(this, "Enter your SKU number here."); }); $("#unitPrice").focus(function() { ShowMessage(this, "Enter the unit price of this product."); }); $("#discountPercentage").focus(function() { ShowMessage(this, "Enter the percent off you want to give for this product."); }); $("#unitsInStock").focus(function() { ShowMessage(this, "Total number of units of this product you have in stock."); }); $("#smallImageURL").focus(function() { ShowMessage(this, "The url to the thumbnail for this product."); }); $("#fullImageURL").focus(function() { ShowMessage(this, "The url to full sized image of this product."); }); function ValidateTitle() { return VerifyRequiredField("#title", "required"); } function ValidateDescription() { return VerifyRequiredField("#description", "required"); } function ValidateProduct() { return ValidateTitle() && ValidateDescription(); } $("form.product-create").validate(ValidateProduct); /*********************************************************************************** * Rich Text Editor ***********************************************************************************/

var bodyEditor; $(document).ready(function() { bodyEditor = new tinymce.Editor("description", __editorConfig); bodyEditor.onChange.add(function(ed) { bodyEditor.save(); }); bodyEditor.onClick.add(function(ed) { ShowMessage("#description", "Enter the description of your product here."); }); bodyEditor.render(); });

// clears the message from the description when another input gets // focus $(":input") .focus(function() { HideMessage("#description"); }) .blur(function() { HideMessage("#description"); });

Page 51: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

45

Trong tệp commerece.js có các đoạn mã lệnh cho cả quản lí gian hàng, quản lí sản phẩm ,… Đoạn code thực hiện xóa gian hàng không tạo ra việc Post back toàn bộ: $(".delete-department-button").click(function() { var departmentId = $(this).attr("meta:id"); $.post( "/Commerce/DeleteDepartment", { id: departmentId }, function(data) { $("#department-" + data.object.id).remove(); $("#admin-" + data.object.id).remove(); $("#spacer-" + data.object.id).remove(); }, "json" ); return false; }); Đoạn code thực hiện việc xóa sản phẩm khỏi gian hàng không tạo ra việc postback toàn bộ: $(".delete-product-button").click(function () { var productID = $(this).attr("meta:id"); $.post( "/Commerce/DeleteProduct", { id: productID }, function (data) { $("#product-" + data.object.id).remove(); $("#admin-" + data.object.id).remove(); $("#spacer-" + data.object.id).remove(); }, "json" ); return false; }); Đoạn code thực hiện việc các phương thức ứng với cách thức vận chuyển (như xóa cách thức vận chuyển, thêm cách thức vận chuyển) mà không tạo ra postback toàn bộ trang ManageShipping.aspx: $(".delete-shipping-method-button").live("click", function() { var shippingMethodId = $(this).attr("meta:id"); $.post( "/Commerce/DeleteShipping", { id: shippingMethodId }, function(data) { $("#shipping-method-" + data.object.id).remove(); },

Page 52: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

46

"json" ); return false; });

$("#add-shipping-method-button").click(function() { var title = $("#title").val(); var price = $("#price").val(); $.post( "/Commerce/CreateShipping", { title: title, price: price }, function(data) { var html = '<tr id="shipping-method-' + data.object.id + '">'; html += '<td align="center">' + title + '</td>'; html += '<td align="center">' + price + '</td>'; html += '<td align="center"><a href="#" class="delete-shipping-method-button" meta:id="' + data.object.id + '"><img border="0" alt="Delete Role" src="/content/images/DeleteSymbol.png" title="Delete Role" align="middle"/></a></td>'; html += '</tr>'; $("#shipping-table tbody").append(html); $("#title").val(""); $("#price").val(""); }, "json" ); return false; }); Đoạn code thực hiện việc xóa sản phẩm khỏi giỏ hàng $(".delete-item-button").click(function () { var productId = $(this).attr("meta:id"); var form = $(this).parent("form"); $.post( "/Commerce/DeleteShoppingCartItem", { id: productId }, function (data) { $("#item-" + data.object.id).remove(); //Reload whole page location.reload(form); }, "json" ); return false; });

Page 53: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

47

3.10. Cấu hình định tuyến

Định tuyến dành cho các view của người dùng có vai trò là storekeeper: routes.MapRoute( "CommerceManageStore", "storekeeper/store", new { controller = "Commerce", action = "ManageStore" } ); routes.MapRoute( "CommerceManageDepartments", "storekeeper/store/departments", new { controller = "Commerce", action = "ManageDepartments" } ); routes.MapRoute( "CommerceCreateDepartment", "storekeeper/store/departments/create", new { controller = "Commerce", action = "CreateDepartment" } ); routes.MapRoute( "CommerceEditDepartment", "storekeeper/store/departments/edit/{departmentId}", new { controller = "Commerce", action = "EditDepartment", departmentId = (int?)null } ); routes.MapRoute( "CommerceManageProducts", "storekeeper/store/products", new { controller = "Commerce", action = "ManageProducts" } ); routes.MapRoute( "CommerceCreateProduct", "storekeeper/store/products/create", new { controller = "Commerce", action = "CreateProduct" } ); routes.MapRoute( "CommerceEditProduct",

Page 54: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

48

"storekeeper/store/products/edit/{productId}", new { controller = "Commerce", action = "EditProduct", productId = (int?)null } ); routes.MapRoute( "CommerceManageOrders", "storekeeper/store/orders", new { controller = "Commerce", action = "ManageOrders" } ); routes.MapRoute( "CommerceOrderDetail", "storekeeper/store/orders/{orderId}", new { controller = "Commerce", action = "OrderDetail", orderId = (int?)null } ); routes.MapRoute( "CommerceManageShipping", "storekeeper/store/shipping", new { controller = "Commerce", action = "ManageShipping" } ); Định tuyến dành cho những người dùng còn lại: routes.MapRoute( "CommerceIndex", "", new { controller = "Commerce", action = "Index" } ); routes.MapRoute( "CommerceDepartment", "store/departments/{departmentId}", new { controller = "Commerce", action = "ViewDepartment", departmentId = (int?)null } ); routes.MapRoute( "CommerceProduct", "store/products/{productId}", new { controller = "Commerce", action = "ViewProduct", productId = (int?)null } ); routes.MapRoute( "CommerceCart", "store/cart",

Page 55: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

49

new { controller = "Commerce", action = "ViewShoppingCart" } ); routes.MapRoute( "CommerceCompleted", "store/order/completed", new { controller = "Commerce", action = "CompleteOrder" } );

Page 56: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

50

4. MODULE GỬI THƢ

4.1. Tổng quan về module

Hệ thống luôn có những nội dung cập nhật mới như bài báo, diễn đàn, thông tin sản phẩm mới … để tạo sự chú ý cho những người dùng là khách hàng thì hệ thống có module gửi thư thông báo khách hàng biết có những thông tin mới đó để rồi khách hàng sẽ quay trở lại sử dụng hệ thống trong trường hợp khách hàng đăng kí nhận thư từ hệ thống.

4.2. Các vấn đề cần quan tâm khi xây dựng module:

Để lưu trữ thông tin đăng kí nhận thư của người dùng ta chỉ cần lưu các thông tin như địa chỉ thư điện tử của người dùng, tên, họ, định dạng thư nhận. Tất cả các thông tin này có trong các bảng của module hồ sơ và thành viên ta hoàn toàn có thể tận dụng. Việc tạo và gửi thư điện tử của người dùng với vai trò là nhà quản trị có thể được xây dựng sử dụng namespace System.Net.Mail (namespace này được định nghĩa trong thư viện System.dll). Các lớp chính cho việc tạo và gửi thư là lớp MailMessage, và lớp SmtpClient cung cấp các phương thức tạo và gửi thư bằng việc kết nối với máy chủ SMTP đã được cấu hình. Với lớp MailMessage ta có thể tạo toàn bộ thông tin đầy đủ của một thư điện tử như sau: // create the message MailMessage mail = new MailMessage(); // set the sender's address and display name mail.From = new MailAddress("[email protected]", "Loc Dang"); // add a first recipient by specifying only her address mail.To.Add("[email protected]"); // add a second recipient by specifying his address and display name mail.To.Add(new MailAddress("[email protected]", "Dan nguyen")); // add a third recipient, but to the CC field this time mail.CC.Add("[email protected]"); // set the mail's subject and HTML body mail.Subject = "Sample Mail"; mail.Body = "Hello, <b>my friend</b>!<br />How are you?"; mail.IsBodyHtml = true; // set the mail’s priority to high mail.Priority = MailPriority.High; // add a couple of attachments mail.Attachments.Add( new Attachment(@"c:\demo.zip", MediaTypeNames.Application.Octet)); mail.Attachments.Add( new Attachment(@"c:\report.xls", MediaTypeNames.Application.Octet));

Page 57: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

51

Khi đối tượng MailMessage đã được tạo ta có thể gửi nó bằng phương thức Send của lớp SmtpClient. SmtpClient smtpClient = new SmtpClient(); smtpClient.Send(mail); Trước khi có thể gọi phương thức Send ta cần thiết lập các thông tin cấu hình cho hệ thống để phương thức này có thể thực hiện được như địa chỉ của máy chủ SMTP (thuộc tính SmtpClient Host), cổng (thuộc tính port) và giấy chứng thực của máy chủ này (thuộc tính credentials), kết nối được mã hóa với SSL (thuộc tính EnableSsl) và thời gian duy trì từ lúc bắt đầu cho tới khi kết thúc của việc gửi thư ( thuộc tính TimeOut, giá trị mặc định là 100 giây). Một thuộc tính quan trọng là DeliveryMethod (đây là thuộc tính liệt kê của kiểu dữ liệu SmtpDeliveryMethod. Nó có thể nhận một trong các giá trị sau: Network: Thư được gửi thông qua kết nối trực tiếp tới một máy chủ Smtp cụ thể PickupDirectoryFromIs: Thư điện tử này được chuẩn bị và tệp thư này được lưu vào thư mục mặc định là <drive>:\Inetpub\mailroot\Queue. IIS sẽ lấy thư này từ hàng đợi thư để gửi. SpecifedPickupDirectory: Các tệp EML với thư điện tử sẽ được gửi được lưu vào thư mục được chỉ định cho thuộc tính này của đối tượng SmtpClient. Thiết lập này sẽ hữu ích khi ta có một ứng dụng ngoài (không phải IIS) xử lí việc chọn thư và gửi Cấu hình phần gửi thư của hệ thống thương mại trực tuyến <system.net> <mailSettings> <smtp deliveryMethod="Network" from="[email protected]">

<network defaultCredentials="true" host="MailServer" port="25"/>

</smtp> </mailSettings> </system.net> Vấn đề thời gian trong xử lí gửi thư có thể là rất lâu khiến người dùng có thể nghĩ hệ thống có lỗi. Việc gửi thư tới hàng ngàn khách hàng đăng kí nhận thư (subscribers) thường phải mất hàng phút trong khi để xử lí một yêu cầu theo tiêu chuẩn chỉ nên trong vài giây. Một giải pháp được đưa ra trong hệ thống đó là khi người dùng nhấn nút submit (tương đương với hành động gửi thư) thì ở phía máy chủ sẽ sinh ra một tiến trình xử lí nhiệm vụ gửi thư mất nhiều thời gian đó ở chế độ nền (backgroudn running mode) và chuyển hướng người dùng về trang quản lí thư. Và ở trang đó người dùng có thể thấy được trạng thái của tất cả các thư đã gửi trong đó có cả thư mới tạo gần nhất và đang được gửi.

Page 58: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

52

Để tránh việc phải có một nút refresh ở trang quản lí thư đó để biết được trạng thái thư mới gửi gần nhất ta sẽ sử dụng JQuery để yêu cầu dư liệu từ lớp điều khiển việc gửi thư (newsletters controller class) và rồi tạo một đối tượng DOM đưa trực tiếp dữ liệu về tình trạng xử lí thư vừa gửi vào trang quản lí thư. Đoạn code javascript đó như sau: $.ajax({ type: "GET", url: "/Newsletter/UpdateStatus", dataType: "html", sucess: function (result) { var domElement = $(result); $("#Newsletter_Status_Table").replaceWith(domElement); } }); Tạo các luồng tiến trình chạy nền – đa tiến trình Các luồng tiến trình chạy nền hay luồng phụ được sử dụng để xử lí các nhiệm vụ cần nhiều thời gian mà không ảnh hưởng tới tiến trình chính. Với ASP.NET ta có thể tạo 250 tiến trình chạy cùng một thời điểm trên một CPU Việc tạo mới một tiến trình không khó tuy nhiên ta phải quan tâm tới việc các tiến trình có thể truy cập cùng lúc tới cùng một không gian nhớ. Để tạo tiến trình ta cần namespace System.Threading trong thư viện mscorlib.dll. Dưới đây là một đoạn code tạo tiến trình phụ chạy nền // create and start a background thread with some input parameters object[] parameters = new object[]{"val1", 10, DateTime.Now}; ParameterizedThreadStart pts = new ParameterizedThreadStart(ExecuteTask); Thread thread = new Thread(pts); thread.Priority = ThreadPriority.BelowNormal; thread.Start(parameters); // main thread goes ahead immediately … // the method run asynchronously by the background thread void ExecuteTask(object data) { // extract the parameters from the input data object object[] parameters = (object[])data; string val1 = (string)parameters[0]; int val2 = (int)parameters[1]; DateTime val3 = (DateTime)parameters[2]; // execute time consuming processing here … }

Page 59: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

53

uc NewsLetters

Registered User

(from Actors)

Administrator

(from Actors)

SubscribeCreate Newsletters

Edit Newsletters Manage Newsletters

Delete Newsletters

«include»

«include»

4.3. Sơ đồ chức năng

Hình 3.12 – Sơ đồ chức năng của module

4.4. Các bảng dữ liệu

Hình 3.13 – Bảng Newsletters Với việc thông tin về người đăng kí nhận thư có thể sử dụng các bảng trong module hồ sơ và thành viên thì với module này chỉ cần một bảng Newsletters thể hiện nội dung thư gửi từ hệ thống, và các thông tin về thư đó.

Page 60: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

54

4.5. Thiết kế lớp cấu hình cho module

Module này sử dụng thành phần <mailsettings> nằm trong <system.net> của tệp web.config. Để cấu hình cho module ta phải xem các thành phần cấu hình của <system.net> /<mailsettings>/<smtp> ở bảng sau

Tiếp đến là cấu hình <system.net>/<mailSettings>/<smtp>/<network>

Cuối cùng ta sẽ tạo thêm phần cấu hình cho module. Phần này thiết lập địa chỉ thư điện tử được sử dụng để gửi thư

4.6. Model

Với module này ta sẽ chỉ cần model là lớp thực thể LINQ-to-SQL dưới đây:

Thuộc tính SMTP Mô tả

DeliveryMethod Thiết lập thuộc tính này với “network” chỉ ra cho ứng dụng biết rằng có một mảy chủ thư điện tử bên ngoài sẽ được sử dụng để gửi thư điện tử. Để gửi được thư thì thành phần của <network> cần được sử dụng gồm có Nơi chứa - Host,Cổng - Port,Tên người dùng - UserName,Mật khẩu- Password, và Chứng thực mặc định - DefaultCredentials.

From Chỉ ra địa chỉ email sẽ được đặt trong mục “From” khi ứng dụng gửi thư đi

ConfigSource Định nghĩa một nguồn ngoài cho các thiết lập cấu hình thư ví dụ như mail.config

Thuộc tính Network Mô tả

DefaultCredentials Một giá trị kiểu bool chỉ ra rằng các chứng thực của ứng dụng có được dùng hay không. Nếu giá trị đó là true thì UserName và Password là không cần

Host Tên của máy chủ thư điện tử

UserName Tên người dùng được sử dụng để đăng nhập vào máy chủ thư điện tử và gửi thư.

Password Mật khẩu được sử dụng để đăng nhập vào máy chủ thư điện tử để gửi thư

Port Cổng sẽ được sử dụng để gửi SMTP

Thuộc tính Newsletters

Mô tả

FromEmail Địa chỉ thư điện tử thực sẽ xuất hiện trong mục “From” trong thư gửi đi ở phần đầu của thư

FromDisplayName Tên hiển thị được sử dụng kèm với thuộc tính FromEmail

Page 61: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

55

Hình 3.14 – Sơ đồ Model Newsletter

4.7. Controller

Với các chức năng của module như sơ đồ chức năng ta có tương ứng các phương thức hành động của controller của module

Phương thức hành động Bảo mật Các tham số

Index ---- ----

ManageNewsletters Editor ----

UpdateStatus Editor ----

CreateNewletters Editor string subject, string body

EditNewsletters Editor int? newsletterId, string subject, string body

RemoveNewsletter Editor int? newsletterId

4.8. View

Từ các phương thức hành động trong phần controller ta cũng có các view dành cho tương ứng. Dưới đây là danh sách các view của module

Tên trang Đặc tả Đường dẫn ảo Index.aspx Trang này được sử

dụng để đăng kí nhận thư từ hệ thống

newsletter

CreateNewsletter.aspx Trang này cho phép người dùng với vai trò là editor tạo hoặc chỉnh sửa thư

editor/newsletter/create editor/newsletter/edit/{newsletterId}

ManageNewsletter.aspx Trang này liệt kê toàn bộ các thư đã gửi trước đó. Editor có thể nhấn vào

editor/newsletter/remove/{newsletterId}

editor/newsletter

Page 62: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

56

thư và xem lại nội dung thư hoặc xóa thư. Trang được cập nhật sau vài giây xử dụng JQuery

4.9. Cấu hình định tuyến

Định tuyến cho trang index của module: routes.MapRoute( "NewsletterIndex", "newsletters", new { controller = "Newsletter", action = "Index" } ); Định tuyến cho các trang dành cho editor: routes.MapRoute( "NewsletterCreate", "editor/newsletters/create", new { controller = "Newsletter", action = "CreateNewsletter" } ); routes.MapRoute( "NewsletterEdit", "editor/newsletters/edit/{newsletterId}", new { controller = "Newsletter", action = "EditNewsletter", newsletterId = (int?)null }, new { newsletterId = "[0-9]+" } ); routes.MapRoute( "NewsletterRemove", "editor/newsletters/remove/{newsletterId}", new { controller = "Newsletter", action = "RemoveNewsletter", newsletterId = (int?)null }, new { newsletterId = "[0-9]+" } ); routes.MapRoute( "NewsletterManage", "admin/newsletters", new { controller = "Newsletter", action = "ManageNewsletters" } );

Page 63: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

57

uc Polls

Editor

(from Actors)Registered User

(from Actors)

View Polls

Vote

Manage PollsRemov e Poll

Edit Poll

Set Archiv e

Set Make Current

Create Poll

Make Poll Question

Make Poll Options

Update Poll

«include»

«include»

«include»

«include»

«include»

«include»

«include»

5. MODULE LẤY Ý KIẾN KHÁCH HÀNG

5.1. Tổng quan về module

Module lấy ý kiến khách hàng gồm các câu hỏi đi kèm với mỗi câu hỏi là các lựa chọn mà khách hàng có thể chọn để trả lời câu hỏi đó. Module được xây dựng vì những lí do như người quản lí hệ thống muốn nắm bắt thị hiếu khách hàng về nhiều vấn đề từ hệ thống cho đến các sản phẩm bán trong siêu thị …Ngoài ra module được xây dựng cũng đem lại cho khách hàng cảm giác họ là một phần của hệ thống và như vậy họ sẽ sử dụng hệ thống thường xuyên hơn. Về mặt chức năng thì module sẽ cho người dùng xem các trưng cầu có trong hệ thống, cho ý kiến. Với người dùng có vai trò là editor có thể quản lí các trưng cầu (chuyển trưng cầu sang trạng thái đã lấy đủ ý kiến, trưng cầu hiện hành và đưa ra trang chủ, chỉnh sửa trưng cầu, xóa trưng cầu), tạo trưng cầu mới.

5.2. Sơ đồ chức năng

Hình 3.15 – Sơ đồ chức năng của module lấy ý kiến người dùng

Page 64: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

58

5.3. Các bảng dữ liệu

Hình 3.16 – Sơ đồ mối quan hệ giữa 2 bảng DL của module lấy ý kiến người dùng Với module này ta cần 2 bảng một bảng là bảng Polls chứa các câu hỏi lấy ý kiến và các thuộc tính của chúng như câu hỏi trưng cầu là hiện hành, hay đã lấy đủ ý kiến … Bảng thứ 2 là bảng PollOptions chứa các thông tin về những chọn lựa cho câu hỏi đặt ra để lấy ý kiến. Mỗi một chọn lựa tương ứng với một câu trả lời được hệ thống tạo sẵn cho người dùng.Quan hệ giữa 2 bảng này được tạo thông qua khóa

ngoại PollD

Hình 3.17 – Sơ đồ thiết kế bảng PollOptions

Page 65: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

59

Hình 3.18 – Sơ đồ thiết kế bảng Polls

5.4. Thiết kế lớp cấu hình cho module

Với module này cần thiết lập một số thông tin cấu hình như thiết lập thuộc tính archived hay public cho một trưng cầu … (khi thiết lập thuộc tính public hay archived cho poll, cho phép hay không cho phép vote nhiều lần..) Bảng dưới đây sẽ là bảng các thuộc tính thuộc lớp PollElement. Lớp này kế thừa từ lớp ConfigurationElement của framework .net mvc. Nó sẽ đọc các thiết lập của thành phần <polls> nằm trong phần thiết lập cầu hình của <GlobalStore> trong tệp web.config

5.5. Model

Model của module này cũng thiết kế theo kiểu mẫu Provider Model của Microsoft như đã trình bày trong phần lựa chọn kiến trúc hệ thống. Có 2 lớp thực thể LINQ-to-SQL được tạo tự động là:

Thuộc tính SMTP Mô tả

VotingLockInterval Một số nguyên cho biết khi nào thì cookie dành cho phần vote của một người dùng cụ thể nào đó hết hiệu lực (tương ứng với số ngày ngăn ngừa việc vote lại)

VotingLockByCookie Một giá trị kiểu bool chỉ ra rằng liệu cookie có được dùng hay không được dùng cho việc nhớ người dùng đã vote hay chưa

VotingLockByIP Một giá trị kiểu bool cho biết liệu địa chỉ IP của người dùng có được giữ trong bộ nhớ để tránh việc một người với cùng 1 địa chỉ IP trong phiên hiện hành vote cho cùng một poll nhiều lần

ArchiveIsPublic Một giá trị kiểu bool được dùng để cho biết liệu các poll đã được thiết lập archive có được xem bởi tất cả mọi người hay không

Page 66: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

60

Hình 3.19 – Sơ đồ lớp PollOption và Poll Lớp tĩnh PollQueries chứa tất cả các truy vấn cần thiết để lấy thông tin từ CSDL cụ thể nó cung cấp các phương thức mở rộng cho module này.

Hình 3.20 – Sơ đồ lớp PollQueries

5.6. Controller

Ứng với các chức năng của module ta có các phương thức hành động trong controller của module ở bảng dưới đây

Phương thức hành động Bảo mật Các tham số

Index ---- bool? archived, int page

ViewPoll ---- int id, string path

Vote ---- int optionId

ManagePolls Editor int page

CreatePoll Editor string question, bool? Current

RemovePoll Editor int? newsletterId

EditPoll Editor int pollId, string question, bool? current, bool? Archived

AddOption Editor int pollId, string text

RemoveOption Editor int optionId

SetCurrent Editor int pollId

SetArchived Editor int pollId, bool archive

Page 67: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

61

5.7. View

Dưới đây là các trang của module dành cho người dùng có vai trò editor và người dùng khác của hệ thống:

Tên trang Đặc tả Đường dẫn ảo

Index.aspx Trang này được sử dụng để xem các poll ở các trạng thái như công khai (public), đã lấy đủ (archived)

/polls /polls/page{page} /polls?archived=true /polls/ page{page}?archived=true

CreatePoll.aspx Trang này cho phép người dùng với vai trò là editor tạo hoặc chỉnh sửa poll

/editor/polls/create / editor /polls/edit/{pollId}

ManagePolls.aspx Trang này liệt kê toàn bộ các poll có trong hệ thống. Editor có thể thêm, chỉnh sửa, xóa các lựa chọn của poll, thiết lập poll hiện hành (set current), và xem poll hiện hành

/ editor /polls / editor /polls/page{page}

RemovePoll.aspx Trang này dùng thực hiện việc xóa poll khỏi hệ thống

/editor/polls/remove/{pollId}

5.8. Sử dụng javascript

Module này sử dụng 2 tệp javascript trong thư mục Content/script là tệp manage-poll.js : /****************************************************************** * Manage ******************************************************************/ $(document).ready(function() { $("#polls :input").hide("fast"); }); $(".set-current").click(function() { var id = $(this).attr("meta:id"); $.post( "/poll/setcurrent", { pollId: id },

Page 68: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

62

function(data) { var poll = $("#set-current-" + data.object.pollId); poll.remove(); }, "json" ); return false; }); $(".set-archived").click(function() { var id = $(this).attr("meta:id"), archived = $(this).hasClass("archived"); $.post( "/poll/setarchived", { pollId: id, archive: !archived }, function(data) { var poll = $("#set-archived-" + data.object.pollId); poll.removeClass("archived"); if (data.object.isArchived) poll.addClass("archived"); poll.text(data.object.isArchived ? "Allow Voting" : "Archive"); }, "json" ); return false; }); /****************************************************************** * Polls ******************************************************************/ $("#question").focus(function() { ShowMessage(this, "Enter the question you would like to ask in the poll."); }); function ValidateQuestion() { return VerifyRequiredField("#question", "required"); } function ValidatePoll() { return ValidateQuestion(); } $("form.poll-create").validate(ValidatePoll);

Page 69: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

63

function EditOption() { var id = $(this).attr("meta:id"), option = $("#option-" + id), text = option.find(".text").text(); // hide all the childrend option.children().hide(); var optionForm = $("<form><span class=\"field\"><input type=\"text\" id=\"text-" + id + "\" class=\"edit-text\" value=\"" + text + "\" /> <button type=\"button\" class=\"update\" meta:id=\"" + id + "\">Update</button>&nbsp;<button type=\"button\" class=\"cancel\">Cancel</button></span></form>"); // update the form optionForm.find(".update").click(function () { var id = $(this).attr("meta:id"), formText = $(this).prevAll(".edit-text").val(); $.post( "/poll/editoption", { optionId: id, text: formText }, function (data) { var comment = $("#option-" + data.object.optionId); comment.children("form").remove(); comment.children(".text").text(data.object.text); comment.children().show(); }, "json" ); }); // cancel the update optionForm.find(".cancel").click(function () { $(this).parents(".option").children(":hidden").show(); $(this).parents("form").remove(); }); // add the form to the current comment option.append(optionForm); return false; } $(".edit-option-button").click(EditOption); function DeleteOption () { var id = $(this).attr("meta:id");

Page 70: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

64

$.post( "/poll/removeoption", { optionId: id }, function (data) { $("#option-" + data.object.optionId).fadeOut("slow", function () { $(this).remove() }); }, "json" ); return false; } $(".delete-option-button").click(DeleteOption); function AddOptionSuccess(data) { var optionItem = $("<li id=\"option-" + data.object.optionId + "\" class=\"option\"><span class=\"text\">" + data.object.text + "</span> <button type=\"button\" class=\"edit-option-button\" meta:id=\"" + data.object.optionId + "\">Edit</button>&nbsp;<button type=\"button\" class=\"delete-option-button\" meta:id=\"" + data.object.optionId + "\">Delete</button></li>"); optionItem.find(".edit-option-button").click(EditOption); optionItem.find(".delete-option-button").click(DeleteOption); // clear the option box $("#option").val(""); // add the new option to the other options optionItem.appendTo("#poll-options"); } $("form.poll-options-create").submit(function() { var option = $("#option").val(), pollId = $("#pollId").val(); $.post( "/poll/addoption", { pollId: pollId, text: option }, AddOptionSuccess, "json" ); return false; }); Và tệp poll.js /******************************************************************

Page 71: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

65

* Poll ******************************************************************/ function RenderPoll(obj, data) { var poll = $(obj), total = data.object.total, item, percentValue, rightValue, leftValue; // clears all child nodes poll.empty(); poll.append("<h2>" + data.object.question + "</h2>"); poll.append("<ul class=\"poll-options\">"); // go through each option and render it for(var i = 0; i < data.object.options.length; i++) { item = data.object.options[i]; percentValue = Math.round(item.votes / total * 100); poll.append("<li class=\"option\" id=\"option-" + item.optionId + "\">" + "<h3>" + item.text + "</h3>" + "<div class=\"graph\"><img src=\"/Content/images/poll-graph.gif\" height=\"10\" width=\"" + percentValue + "%\" /></div>" + "<div class=\"values\">" + percentValue + "% (" + item.votes + " votes)</div>" + "</li>"); } poll.append("</ul>"); poll.append("<div class=\"total\">There are " + total + " total votes for this poll.</div>"); } $(".poll form").submit(function() { var selection = $(this).find(":checked").val(); if (selection != undefined) { $.post( "/poll/vote", { optionId: selection }, function(data, textStatus) { SetCookie("poll_" + data.object.pollId, selection, 30); // render the poll for the given data RenderPoll($("#poll-" + data.object.pollId), data); }, "json" ); }

Page 72: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

66

return false; });

5.9. Cấu hình định tuyến

Định tuyến của các trang dành cho người dùng không có vai trò editor routes.MapRoute( "PollsIndex", "polls", new { controller = "Poll", action = "Index", page = 1 } ); routes.MapRoute( "PollsIndexPaged", "polls/page{page}", new { controller = "Poll", action = "Index", page = (int?)null }, new { page = "[0-9]+" } ); Định tuyến dành của các trang dành cho người dùng có vai trò là editor routes.MapRoute( "PollCreate", "admin/polls/create", new { controller = "Poll", action = "CreatePoll" } ); routes.MapRoute( "PollEdit", "admin/polls/edit/{pollId}", new { controller = "Poll", action = "EditPoll", pollId = (int?)null }, new { pollId = "[0-9]+" } ); routes.MapRoute( "PollRemove", "admin/polls/remove/{pollId}", new { controller = "Poll", action = "RemovePoll", pollId = (int?)null }, new { pollId = "[0-9]+" } ); routes.MapRoute( "PollManager",

Page 73: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

67

"admin/polls", new { controller = "Poll", action = "ManagePolls", page = 1 } ); routes.MapRoute( "PollManagerPaged", "admin/polls/page{page}", new { controller = "Poll", action = "ManagePolls", page = (int?)null }, new { page = "[0-9]+" } );

Page 74: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

68

uc Forums

Editor

(from Actors)

User

(from Actors)

View All Forums

View Forum

ViewPost

Create Post

Manage Forum

Edit Forum

Remov e Forum

Close Post

Approv e Post

Remov e Post

«include»

«include»

6. MODULE DIỄN ĐÀN

6.1. Tổng quan về module

Là một công ty sở hữu các chuỗi siêu thị có mặt khắp nơi trên thế giới ,Global Store có rất nhiều khách hàng trung thành. Các khách hàng của Global Store có chung nhiều sở thích mà mua sắm tại các siêu thị của công ty là một trong những sở thích đó. Nhu cầu giao lưu trao đổi về những sở thích đó là hết sức tự nhiên. Nắm bắt được điểm này Global Store đã xây dựng diễn đàn tạo một sân chơi cho các khách hàng của công ty giao lưu. Diễn đàn góp phần giữa chân các khách hàng trung thành cũng như biến các khách hàng tiềm năng thành khách hàng thân thiết của công ty. Sử dụng module này người dùng nạc danh có thể duyệt xem bài bình luận trong các diễn đàn, tuy nhiên để gửi bài hay bình luận họ phải đăng nhập vào hệ thống. Chức năng quản lí diễn đàn, quản lí các bài thỏa luận dành cho người dùng có vai trò là editor. (biên tập)

6.2. Sơ đồ chức năng

Hình 3.21 – Sơ đồ chức năng module Forum

Page 75: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

69

6.3. Các bảng dữ liệu

Hình 3.22 – Các bảng dữ liệu của module forum Trong module này ta cần có 3 bảng như hình vẽ. Ngoài 2 bảng Forums và Posts là các bảng cốt lõi cho một diễn đàn thì ta có thêm bảng vote dùng cho cho ý kiến một cho một post là hay hay không để người dùng có thể biết post đó được nhiều hay ít người quan tâm, thích.

6.4. Xây dựng lớp ForumsElement cho thiết lập cấu hình module

Các thiết lập về module Diễn đàn được định nghĩa trong thành phần <forums> trong mục <GlobalStore> của tệp web.config. Lớp này ánh xạ các thiết lập về diễn đàn ứng với các thuộc tính của nó để sử dụng cho module

6.5. Model

Model của module này cũng được thiết kế theo kiểu mẫu Provider Model được trình bày ở phần thiết kế kiến trúc hệ thống gồm có các lớp thực thể LINQ-to-SQL

Thuộc tính SMTP Mô tả

PostReplyPageSize Số các trả lời với mỗi một post trên một trang khi người dùng xem một post

ForumPageSize Số lượng các post liệt kê ở mỗi trang khi xem một diễn đàn

Page 76: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

70

và một lớp ForumQueries chứa các phương thức mở rộng hỗ trợ truy vấn của module như hình vẽ dưới

Hình 3.23 – Sơ đồ các lớp thực thể LINQ-to-SQL Post, Forum, Vote

Hình 3.24 – Sơ đồ lớp ForumQueries

6.6. Controller

Phương thức hành động Bảo mật Các tham số

Index ---- ----

ViewForum ---- int forumId, string path, int page

ViewPost ---- Int postId, string path

Vote ---- int post Id, int direction

Page 77: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

71

ManageForum Editor int? newsletterId, string subject, string body

CreateForum Editor string title, string description, int? order, bool? Moderated

EditForum Editor int forumId, string title, string description, int? order, bool? Moderated

RemoveForum Editor int forumId, string remove

CreatePost ---- int? forumId, int? parentPostId, string title, string body

ClosePost Editor int postId, bool closed

ApprovedPost Editor int postId, bool approved

RemovePost Editor int posted

6.7. View

Tên trang Đặc tả Đường dẫn ảo

Index.aspx Trang này dùng để xem danh sách tất cả các forums có trong hệ thống

/Forum

ViewForum.aspx Thông quan trang này người dùng có thể xem các post có trong một forum

forums/{forumId}/{*path} forums/{forumId}/{path}/page{page}

ViewPost.aspx Đây là trang cung cấp view cho một post và các reply của post đó

forums/posts/{postId}/{*path} forums/posts/{postId}/{path}/page{page}

CreatePost.aspx Đây là trang mà qua đó người dùng có thể tạo post mới hoặc trả lời một post nào đó

forums/posts/{postId}/{*path} forums/posts/{postId}/{path}/page{page}

ManageForums.aspx Đây là trang mà qua đó editor có thể quản lí diễn đàn với chức năng thêm, sửa và xóa nội dung

editor/forums

ManagePosts.aspx Đây là trang mà qua đó người dùng với vai trò editor có thể cho phép hay từ chối một post đang ở trong tình trạng hạn chế

editor/forums/posts

Page 78: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

72

CreateForum.aspx Trang này cho phép editor tạo hay chỉnh sửa một diễn đàn đang tồn tại

editor/forums/create editor/forums/edit/{forumId}

RemoveForum.aspx Trang này dùng để hỏi liệu bạn có muốn xóa điễn đàn khỏi CSDL hay không

editor/forums/remove/{forumId}

6.8. Sử dụng javascript

Trong module này có sử dụng 2 tệp javascript là manage-forum.js và forums.js Tệp manage-forum.js /****************************************************************** * Forum Post ******************************************************************/ $("#title").focus(function() { ShowMessage(this, "Enter the title for your forum."); }); $("#description").focus(function() { ShowMessage(this, "Enter the description of your forum."); }); $("#moderated").focus(function() { ShowMessage(this, "Do you want this forum to be moderated?"); }); $("#order").focus(function() { ShowMessage(this, "The order you want this forum to appear in, compared to the other forums."); }); function ValidateTitle() { return VerifyRequiredField("#title", "required"); } function ValidateDescription() { return VerifyRequiredField("#description", "required"); } function ValidateForum() { return ValidateTitle() && ValidateDescription(); } $("form.forum-create").validate(ValidateForum); /****************************************************************** * Editor Functions ******************************************************************/ $(".post .toggle-body").click(function() { $(this).next(".body").slideToggle("normal");

Page 79: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

73

return false; }); $(".post .admin .close").click(function() { var postId = $(this).attr("meta:id"); $.post( "/forum/closepost", { postId: postId, closed: true }, function(data) { $("#post-" + data.object.postId) .fadeOut("normal", function() { var title = $(this).find("h3"); title.text(title.text() + " [closed]"); $(".admin .close", this).remove(); }) .fadeIn("normal"); }, "json" ); return false; }); $(".post .admin .approve").click(function() { var postId = $(this).attr("meta:id"); $.post( "/forum/approvepost", { postId: postId, approved: true }, function(data) { $("#post-" + data.object.postId).fadeOut("normal", function() { $(this).remove(); }); }, "json" ); return false; }); $(".post .admin .remove").click(function() { var postId = $(this).attr("meta:id"); $.post( "/forum/removepost", { postId: postId }, function(data) {

Page 80: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

74

$("#post-" + data.object.postId).fadeOut("normal", function() { $(this).remove(); }); }, "json" ); return false; }); $(".reply .admin .remove").click(function() { var postId = $(this).attr("meta:id"); $.post( "/forum/removepost", { postId: postId }, function(data) { $("#reply-" + data.object.postId).fadeOut("normal", function() { $(this).remove(); }); }, "json" ); return false; }); Tệp forums.js /********************************************************************************************* * Forum Post *********************************************************************************************/ $("#title").focus(function() { ShowMessage(this, "Enter the title for your post."); }); $("#body").focus(function() { ShowMessage(this, "Enter the body of your post."); }); function ValidateTitle() { return VerifyRequiredField("#title", "required"); } function ValidateBody() { return VerifyRequiredField("#body", "required"); } function ValidatePost() { return ValidateTitle() && ValidateBody();

Page 81: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

75

} $("form.post-create").validate(ValidatePost); /****************************************************************** * Rich Text Editor ******************************************************************/ var bodyEditor; $(document).ready(function() { bodyEditor = new tinymce.Editor("body", __editorConfig); bodyEditor.onChange.add(function(ed) { bodyEditor.save(); }); bodyEditor.onClick.add(function(ed) { ShowMessage("#body", "Enter the body of your article."); }); bodyEditor.render(); }); // clears the message from the description when another input gets focus $(":input") .focus(function() { HideMessage("#body"); }) .blur(function() { HideMessage("#body"); }); /****************************************************************** * Forum ******************************************************************/ function VoteSuccess(data) { if (data.object.error) { alert("You must be logged in to vote."); return; } var button = $(".post .vote-" + (data.object.direction > 0 ? "up" : "down")); var number = $(".post strong"); // remove current selections and select correct button $(".post .vote-button a").removeClass("selected"); button.addClass("selected"); // set new count value number.text(data.object.voteCount); } $(".post .vote-button a").click(function() { var postId = $("#postId").val(); var href = $(this).attr("href"); var direction = (href == "#up") ? 1 : -1;

Page 82: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

76

$.post( "/forum/vote", { postId: postId, direction: direction }, VoteSuccess, "json" ); return false; });

6.9. Cấu hình định tuyến

Định tuyến cho người dùng có vai trò editor: routes.MapRoute( "ForumCreate", "editor/forums/create", new { controller = "Forum", action = "CreateForum" } ); routes.MapRoute( "ForumEdit", "editor/forums/edit/{forumId}", new { controller = "Forum", action = "EditForum", forumId = (int?)null }, new { forumId = "[0-9]+" } ); routes.MapRoute( "ForumRemove", "editor/forums/remove/{forumId}", new { controller = "Forum", action = "RemoveForum", forumId = (int?)null }, new { forumId = "[0-9]+" } ); routes.MapRoute( "ForumPostsManager", "editor/forums/posts", new { controller = "Forum", action = "ManagePosts" } ); routes.MapRoute( "ForumManager", "editor/forums", new { controller = "Forum", action = "ManageForums" } ); Các định tuyến cho người dùng với các vai trò còn lại của hệ thống

Page 83: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

77

routes.MapRoute( "ForumPostCreate", "forums/{forumId}/post", new { controller = "Forum", action = "CreatePost", forumId = (int?)null }, new { forumId = "[0-9]+" } ); routes.MapRoute( "ForumPostReply", "forums/posts/{parentPostId}/reply", new { controller = "Forum", action = "CreatePost", parentPostId = (int?)null }, new { parentPostId = "[0-9]+" } ); routes.MapRoute( "ForumsIndex", "forums", new { controller = "Forum", action = "Index" } ); routes.MapRoute( "Forum", "forums/{forumId}/{*path}", new { controller = "Forum", action = "ViewForum", forumId = (int?)null, path = (string)null, page = 1 }, new { forumId = "[0-9]+" } ); routes.MapRoute( "ForumPaged", "forums/{forumId}/{path}/page{page}", new { controller = "Forum", action = "ViewForum", forumId = (int?)null, path = (string)null, page = (int?)null }, new { forumId = "[0-9]+" } ); routes.MapRoute( "ForumPost", "forums/posts/{postId}/{*path}", new { controller = "Forum", action = "ViewPost", postId = (int?)null, path = (string)null, page = 1 }, new { postId = "[0-9]+" } ); routes.MapRoute( "ForumPostPaged", "forums/posts/{postId}/{path}/page{page}",

Page 84: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

78

new { controller = "Forum", action = "ViewPost", postId = (int?)null, path = (string)null, page = (int?)null }, new { postId = "[0-9]+" } );

6.10. Cấu hình trong tệp web.config

<globalStore> <forums postReplyPageSize="10" forumPageSize="25"/> </globalStore>

Page 85: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

79

uc Articles, News, Blog

Editor

(from Actors)User

(from Actors)

View all categories View all articles of

specific category

View Article Detail

Create Comment

Rate Article

Manage Article

CategoriesRemov e Category

Edit Category

Create Category

Manage Articles

Edit Article

Remov e Article

Create Article

Manage CommentsEdit Comment

Remov e Comment

«include»

«include»

«include»

«include»

«include»

«include»

7. MODULE BÀI BÁO, TIN TỨC, VÀ BLOG

7.1. Tổng quan về module

Global store với mục tiêu tạo một site thương mại tương tác cao nội dung phong phú nên trong hệ thống có module cho phép người dùng viết bài xung quanh các nội dung về sự kiện nào đó tổ chức tại siêu thị, chia sẻ các hình ảnh về siêu thị ,… Người dùng sử dụng module này có thể xem toàn bộ các bài báo, xem theo đầu mục, xem chi tiết bài báo, viết lời bịnh và đánh giá . Người dùng với vai trò là editor có thêm các chức năng như quản lí các đầu mục báo, tạo đầu mục mới, xóa đầu mục đang có trong hệ thống. Quản lí các bài báo (chỉnh sửa, xóa), tạo bài báo mới

7.2. Sơ đồ chức năng

Hình 3.25 – Sơ đồ chức năng của module bài báo, tin tức, và blog

Page 86: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

80

7.3. Các bảng dữ liệu

Với module này ta sẽ cần ba bảng dữ liệu là Articles (chứa các thông tin liên quan đến các bài báo), Categories (Chứa các thông tin liên quan đến đầu mục các bài báo), Comments (Chứa các thông tin liên quan đến bình luận của các bài báo) Mổi quan hệ giữa bảng Articles với bảng Comments được thiết lập thông qua khóa ngoại là ArticleID với updates và deletes là kiểu Cascade do đó khi xóa một Artile thì các Comments tương ứng với Article đó cũng bị xóa. Tương tự quan hệ giữa 2 bảng Categories và Articles được thiết lập thông qua khóa ngoại là CategoryID với updates và deletes là kiểu do đó khi xóa một Category thì các bài báo thuộc Category đó cũng bị xóa.

Hình 3.26 – Sơ đồ bảng Categories, Comments, Articles và quan hệ của chúng

7.4. Xây dựng lớp ArticleElement cho thiết lập cấu hình của

module

Các thuộc tính cấu hình trong thành phần <article> nằm trong phần <globalStore> thuộc tệp web.config sẽ được đọc bởi lớp ArticleElement. Lớp này kế thừa từ namespace System.Configuration.ConfigurationElement với thuộc tính thiết lập cấu hình như trong bảng sau.

Page 87: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

81

Phần cấu hình của module bài báo, tin tức, blog trong tệp web.config <globalStore> <articles pageSize="10"/> </globalStore>

7.5. Model

Từ các bảng DL của module trong CSDL của hệ thống ta tạo được các lớp thực thể tương ứng thông quan LINQ-to-SQL như sau:

Hình 3.27 – Sơ đồ các lớp thực thể Article, Comment, Category Để hỗ trợ cho việc truy vấn các bảng dữ liệu của module. Vì các lớp thực thể Article, Comment, Category đều là các lớp partial do đó có thể thêm các thuộc tính và phương thức vào các lớp này ở một tệp khác tệp chứa định nghĩa của các lớp đó. Như vậy có thể dễ dàng mở rộng các lớp thực thể LINQ-to-SQL được tạo tự động từ các bảng DL trong CSDL của hệ thống.

Thuộc tính Mô tả

PageSize Số các bài báo mặc định có trên mỗi trang.

Page 88: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

82

Như sơ đồ dưới ta có mở rộng cho lớp Article thực thể bằng việc thêm ba thuộc tính AverageRating, Location, Published và 2 phương thức là IncrementViewCount, Rate.Thêm vào đó là một đối tượng ArticleCollectionWrapper

Hình 3.28 – Sơ đồ các lớp mở rộng ArticlesQueries, Article, ArticleCollectionWrapper

7.6. Controller

Phương thức hành động

Bảo mật

Các tham số

Index ---- string category, int page

CategoryIndex ---- ----

ViewArticle ---- int id, string path

RateArticle ---- int articleId, int rating

ManageArticle Editor int page

ManageCategory Editor ----

ManageComment Editor ----

CreateArticle Editor int? categoryId, string title, string summary, string body, string country, string state,string city, DateTime? releaseDate, DateTime? expireDate,

Page 89: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

83

bool? approved, bool? listed, bool? commentsEnabled, bool? onlyForMembers

EditArticle Editor int articleId, int? categoryId, string title, string summary, string body, string country,string state, string city, DateTime? release-Date, DateTime? expireDate, bool? approved, bool? listed, bool? commentsEnabled, bool? onlyForMembers

RemoveArticle Editor int articleId, string remove

CreateCategory Editor string title, int? importance, string imageUrl, string description

EditCategory Editor int categoryId, string title, int? importance, string imageUrl, string description

RemoveCategory Editor int categoryId, int? newCategoryId,string remove

CreateComment ---- int articleId, string name, string email,string body

EditComment Editor int commentId, string name, string body

RemoveComment Editor int commented

7.7. View

Tên trang Đặc tả Đường dẫn ảo Index.aspx Trang này hiển thị

tất cả các bài báo hiện có trong hệ thống

article articles/page{page}} articles/categories/{category} articles/categories/{category}/page{page}

CategoryIndex.aspx Trang này hiển thị những đầu mục các bài báo

articles/categories

ViewArticle.aspx Trang này cho phép xem chi tiết bài báo, viết lời bình luận về bài báo, cho điểm bài báo

articles/{id}/{*path}

ManageArticle.aspx Trang này liệt kê các bài báo hiện có trong hệ thống với hỗ trợ phân trang, và cho phép chỉnh sửa, xóa bài báo

editor/articles editor/articles/page{page}

ManageCategory.aspx Trang này liệt kê các đầu mục báo hiện có trong hệ thống, và cho phép chỉnh sửa, xóa các đầu mục đó

editor/articles/categories

ManageComments.aspx Trang này hiển thị tất cả các lời bình theo thứ tự từ trên xuống từ tính theo thời gian và

Page 90: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

84

cho phép người dùng với vai trò editor xóa các lời bình đó

editor/articles/comments editor/articles/comments/page{page}

CreateArticle.aspx

Trang này cho phép bạn tạo mới hay chỉnh sửa một bài báo có trong hệ thống

editor/articles/create editor/articles/edit/{articleId}

CreateCategory.aspx Trang này cho phép bạn tạo mới hay chỉnh sửa một đầu mục báo có trong hệ thống

editor/articles/categories/create editor/articles/categories/edit/{categoryId}

RemoveArticle.aspx Trang này được dùng để xác nhận lại việc có hay không xóa một bài báo

editor/articles/remove/{articleId}

RemoveCategory.aspx Trang này được dùng để xác nhận lại việc có hay không xóa một đầu mục báo

editor/articles/categories/remove/{categoryId}

7.8. Sử dụng javascript

Tệp manage-category.js được sử dụng để thực thi các hành động phía người dùng trên trang CreateCategory.aspx

Phần đầu của tệp này dùng cho thông điệp thông tin cho các mục trong form Create Category $("#title").focus(function ()

{ ShowMessage(this, "Enter the title for your category."); }); $("#importance").focus(function ()

{ ShowMessage(this, "(optional) Enter the order of importance that you want the categories shown in."); });

$("#imageUrl").focus(function () { ShowMessage(this, "The relative web path of an image you want to be shown with articles in this category."); });

$("#description").focus(function () { ShowMessage(this, "Enter a short description of the category to display to your users."); });

Với đoạn mã lệnh trên thì khi các textbox tittle, importance, imageUrl, hay description được sử dụng thì chúng sẽ hiển thị thông điệp được truyền vào phương thức ShowMessage.

Page 91: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

85

function ValidateTitle () { return VerifyRequiredField("#title", "required"); } function ValidateImageUrl () { return VerifyRequiredField("#imageUrl", "required"); } function ValidateDescription () { return VerifyRequiredField("#description", "required"); } 3 hàm này thực thi việc đảm bảo các trường title, imageUrl, và description có chứa giá trị bởi lẽ chúng buộc phải có để có thể lưu một bản category vào CSDL. function ValidateCategory () { var validTitle = ValidateTitle(); var validImage = ValidateImageUrl(); var validDescription = ValidateDescription(); return validTitle && validImage && validDescription; } $("form.category-create").validate(ValidateCategory); Hàm cuối cùng này của tệp manage-categories.js thực hiện việc đảm bảo cả ba trường đều phải chứa giá trị. Trong trường hơp cả ba trường đều có chứa giá trị nó sẽ trả về giá trị true và như vậy hệ thống sẽ tiếp tục submit Form tạo Category. Trong các trường hợp còn lại hệ thống sẽ không thể tiếp tục thực hiện việc submit Form nói trên.

Tiếp đến là tệp manage-articles.js: Phần đầu của tệp này cũng thực hiện việc tương tự với tệp trên tuy nhiên là cho trang CreateArticles $("#title").focus(function ()

{ ShowMessage(this, "Enter the title for your article."); }); $("#summary").focus(function ()

{ ShowMessage(this, "(optional) Enter a summary for your article to be displayed instead of body."); });

$("#body").focus(function () { ShowMessage(this, "Enter the body of your article."); });

$("#country").focus(function () { ShowMessage(this, "(optional) Enter the country that is associated with this article."); });

$("#state").focus(function () { ShowMessage(this, "(optional) Enter the state that is associated with this article."); });

$("#city").focus(function ()

Page 92: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

86

{ ShowMessage(this, "(optional) Enter the city that is associated with this article."); });

$("#releaseDate").focus(function () { ShowMessage(this, "(optional) This is the date that you want this article to be first show on the site. If left blank todays day is used."); });

$("#expireDate").focus(function () { ShowMessage(this, "(optional) This is the date that you want this article to stop showing on the site."); });

function ValidateTitle () { return VerifyRequiredField("#title", "required"); } function ValidateBody () { return VerifyRequiredField("#body", "required"); } function ValidateArticle () { return ValidateTitle() && ValidateBody(); } $("form.article-create").validate(ValidateArticle); Phần tiếp theo của tệp này được dùng để tạo và gắn một thể hiện của TinyMCE với TextArea có tên là body: var bodyEditor; $(document).ready(function () { bodyEditor = new tinymce.Editor("body", __editorConfig); bodyEditor.onChange.add(function (ed) { bodyEditor.save(); }); bodyEditor.onClick.add(function (ed) { ShowMessage("#body", "Enter the body of your article."); }); bodyEditor.render(); }); Phần code cuối cùng của tệp này dùng để dấu thông điệp của phần body mỗi khi một vùng textbox trên trang CreateArticle được sử dụng: $(":input") .focus(function () { HideMessage("#body"); }) .blur(function () { HideMessage("#body"); });

Tệp manage-comment.js Phần mã lệnh javascript dùng để xóa một comment : $(".remove-comment").click(function () {

Page 93: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

87

var id = $(this).attr("meta:id"); $.post( "/article/removecomment", { commentId: id }, function (data) { $("#comment-" + data.object.commentId).next(".admin").fadeOut("slow", function () { $(this).remove() }); $("#comment-" + data.object.commentId).fadeOut("slow", function () { $(this).remove() }); }, "json" ); return false; }); Phần mã lệnh chỉnh sửa comment: $(".edit-comment").click(function () { var id = $(this).attr("meta:id"), comment = $("#comment-" + id), bodyText = comment.find(".body").text(), nameText = comment.find(".name").text();

// hide all the childrend comment.children().hide(); var commentText = ""; commentText += "<form><div class=\"comment-header field\"><label for=\"name-" + id + "\">Commentor's Name</label><br/><input type=\"text\" id=\"name-" + id + "\" class=\"edit-name\" value=\"" + nameText + "\" /></div>"; commentText += "<div class=\"field\"><label for=\"body-" + id + "\">Comment Body</label><br/><textarea class=\"edit-body\" id=\"body-" + id + "\">" + bodyText + "</textarea><br/><button type=\"button\" class=\"update\" meta:id=\"" + id + "\">Update</button>&nbsp;<button type=\"button\" class=\"cancel\">Cancel</button></div></form>"; var commentForm = $(commentText); // update the form commentForm.find(".update").click(function () { var id = $(this).attr("meta:id"); var nameFormText = $(this).prevAll(".edit-name").val(); var bodyFormText = $(this).prevAll(".edit-body").val(); $.post(

Page 94: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

88

"/article/editcomment", { commentId: id, name: nameFormText, body: bodyFormText }, function (data) { var comment = $("#comment-" + data.object.commentId); comment.children("form").remove(); comment.children(".body").text(data.object.body); comment.children(".name").text(data.object.name); comment.children().show(); }, "json" ); }); // cancel the update commentForm.find(".cancel").click(function () { $(this).parents(".comment").children(":hidden").show(); $(this).parents("form").remove(); }); // add the form to the current comment comment.append(commentForm); return false; });

Tệp article.js Phần code cho điểm một bài báo (rating article). Để cho điểm một bài báo thì việc đầu tiên là phải gắn kết mã lệnh javascript xử lí việc cho điểm với sự kiện submit trên form cho điểm bài báo để mỗi khi người dùng nhấn nút cho điểm thì một yêu cầu AJAX sẽ được gửi tới phương thức hành động /article/ratearticle: $("form.rate-article").submit(function () { $.post( "/article/ratearticle", { articleId: $("#articleId").val(), rating: $("#rating").val() }, RateArticleSuccess, "json" ); // don't allow submit because this is an ajax request return false; });

Page 95: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

89

Bởi lẽ cái yêu cầu cho điểm này là bất đồng bộ nên ta sẽ cung cấp một phương thức callback là RateArticleSuccess. Phương thức này được gọi khi mà việc cho điểm thành công và trả về trình duyệt của người dùng function RateArticleSuccess (data) { var value = data.object.averageRating; var imagePosition = "50"; if (value <= 1.3) imagePosition = "10"; else if (value <= 1.8) imagePosition = "15"; else if (value <= 2.3) imagePosition = "20"; else if (value <= 2.8) imagePosition = "25"; else if (value <= 3.3) imagePosition = "30"; else if (value <= 3.8) imagePosition = "35"; else if (value <= 4.3) imagePosition = "40"; else if (value <= 4.8) imagePosition = "45"; $("#article-rating-value") .replaceWith("<img src=\"/Content/images/stars" + imagePosition + ".gif\" alt=\"" + value + "\" />"); $("form.rate-article :input").attr("disabled", "true"); $("form.rate-article").append("Your rating has been applied!"); } Phần code cho xử lí thêm comment cũng như phần cho điểm bài báo phải thực hiện 2 việc : Một là tạo một yêu cầu bất đồng bộ, hai là thực hiện đáp trả yêu cầu function ValidateCommentName () { return VerifyRequiredField("#comment-name", "required"); } function ValidateCommentEmail () { return VerifyRequiredField("#comment-email", "required"); } function ValidateCommentBody () { return VerifyRequiredField("#comment-body", "required"); } function CreateCommentSuccess (data, textStatus) { $(".new-comment").removeClass("new-comment").show("normal");

Page 96: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

90

var commentText = ""; commentText += "<div id=\"comment-" + data.object.commentId + "\" class=\"comment new-comment\">"; commentText += "<div class=\"comment-header\">Comment posted by " + data.object.name + " 0 sec ago</div>"; commentText += "<blockquote>" + data.object.body + "</blockquote>"; commentText += "</div>"; var comment = $(commentText); // clear the body box $("#comment-body").val(""); // add the new comment to the other comments comment .hide() .appendTo("#article-comments") .slideDown("slow"); } $("form.comment-create").submit(function () { var valid = ValidateCommentName() && ValidateCommentEmail() && ValidateCommentBody(); if (valid) { $.post( "/article/createcomment", { articleId: $("#articleId").val(), name: $("#comment-name").val(), email: $("#comment-email").val(), body: $("#comment-body").val() }, CreateCommentSuccess, "json" ); } // don't allow submit because this is an ajax request return false; });

7.9. Cấu hình định tuyến

Phần cấu hình định tuyến các trang dành cho mọi người dùng: routes.MapRoute( "ArticleView", "articles/{id}/{*path}",

Page 97: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

91

new { controller = "Article", action = "ViewArticle", id = (string)null, path = (string)null }, new { id = "[0-9]+", path = "[a-zA-Z0-9\\-]*" } ); routes.MapRoute( "ArticleCategoryViewIndex", "articles/categories/{category}", new { controller = "Article", action = "Index", category = (string)null, page = 1 }, new { category = "[a-zA-Z0-9\\-]+", page = "[0-9]+" } ); routes.MapRoute( "ArticleCategoryViewIndexPaged", "articles/categories/{category}/page{page}", new { controller = "Article", action = "Index", category = (string)null, page = (int?)null }, new { category = "[a-zA-Z0-9\\-]+", page = "[0-9]+" } ); routes.MapRoute( "ArticleCategoryIndex", "articles/categories", new { controller = "Article", action = "CategoryIndex" } ); routes.MapRoute( "ArticleIndex", "Articles", new { controller = "Article", action = "Index", category = (string)null, page = 1 } ); routes.MapRoute( "ArticleIndexPaged", "articles/page{page}", new { controller = "Article", action = "Index", category = (string)null, page = (int?)null }, new { page = "[0-9]+" } ); Phần cấu hình định tuyến dành riêng cho người dùng có vai trò editor routes.MapRoute( "ArticleCreate",

Page 98: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

92

"editor/articles/create", new { controller = "Article", action = "CreateArticle" } ); routes.MapRoute( "ArticleEdit", "editor/articles/edit/{articleId}", new { controller = "Article", action = "EditArticle", articleId = (int?)null }, new { articleId = "[0-9]+" } ); routes.MapRoute( "ArticleRemove", "editor/articles/remove/{articleId}", new { controller = "Article", action = "RemoveArticle", articleId = (int?)null }, new { articleId = "[0-9]+" } ); routes.MapRoute( "ArticleManage", "editor/articles", new { controller = "Article", action = "ManageArticles", page = 1 } ); routes.MapRoute( "ArticleManagePaged", "editor/articles/page{page}", new { controller = "Article", action = "ManageArticles", page = (int?)null }, new { page = "[0-9]+" } ); routes.MapRoute( "ArticleCategoryCreate", "editor/articles/categories/create", new { controller = "Article", action = "CreateCategory" } ); routes.MapRoute( "ArticleCategoryEdit", "editor/articles/categories/edit/{categoryId}", new { controller = "Article", action = "EditCategory", categoryId = (int?)null }, new { categoryId = "[0-9]+" } );

Page 99: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

93

routes.MapRoute( "ArticleCategoryRemove", "editor/articles/categories/remove/{categoryId}", new { controller = "Article", action = "RemoveCategory", categoryId = (int?)null }, new { categoryId = "[0-9]+" } ); routes.MapRoute( "ArticleCategoryManage", "editor/articles/categories", new { controller = "Article", action = "ManageCategories" } ); routes.MapRoute( "ArticleCommentManage", "editor/articles/comments", new { controller = "Article", action = "ManageComments", page = 1 } ); routes.MapRoute( "ArticleCommentManagePaged", "editor/articles/comments/page{page}", new { controller = "Article", action = "ManageComments", page = (int?)null }, new { page = "[0-9]+" } ); #endregion #endregion #region Polls routes.MapRoute( "PollsIndex", "polls", new { controller = "Poll", action = "Index", page = 1 } ); routes.MapRoute( "PollsIndexPaged", "polls/page{page}", new { controller = "Poll", action = "Index", page = (int?)null }, new { page = "[0-9]+" } );

Page 100: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

94

8. MODULE QUỐC TẾ HÓA

8.1. Tổng quan về module

GlobalStore Pte. có chuỗi các siêu thị có mặt ở nhiều nước vì vậy hệ thống siêu thị trực tuyến của GlobalStore Pte. cần đáp ứng được việc thể hiện hệ thống dưới nhiều ngôn ngữ khác nhau và sử dụng đúng các số liệu như tiền, cách viết ngày tháng, con số theo địa phương của người sử dụng hệ thống. Người sử dụng hệ thống sẽ chọn lựa chức năng này của hệ thống thông qua quá trình đăng kí hồ sơ hoặc chỉnh sửa hồ sơ chọn ngôn ngữ hiển thị của site.

8.2. Xây dựng module

8.2.1. Các Service hỗ trợ quốc tế hóa trong Framework của Microsoft

Namespace System.Globalization cung cấp một số các service hỗ trợ cho việc quốc tế hóa ứng dụng chẳng hạn như lớp CultureInfo được dùng để định dạng ngày và số ứng với những nơi khác nhau.

Tất cả các tiến trình của .NET đều xử lí ,theo dấu đối tượng CurrentCulture ( một đối tượng của lớp CultureInfo xác định các định dạng, các thiết lập sắp xếp) và đối tượng CurrentUICulture (cũng là một đối tượng của lớp CultureInfo xác định ngôn ngữ nào được dùng cho văn bản thể hiện trên giao diện người dùng).

Visual Studio có chương trình soạn thảo tài nguyên sẵn trong nó và giúp ta có thể trực tiếp quản lí việc dịch các chuỗi sang các ngôn ngữ khác. Trong quá trình phát triển ta có thể truy cập tới các chuỗi này thông qua tính năng intelliSense của Visual Studio bởi lẽ mỗi tài nguyên chuỗi khi được tạo ra thì Visual Studio sẽ sinh ra một lớp với các thuộc tính tác biệt cho mỗi chuỗi tài nguyên. Tại thời điểm chạy chương trình, các thuộc tính này gọi System.Resources.ResourceManager (trình quản lí tài nguyên) để trả về phần dịch chuỗi tài nguyên tương ứng với tiến trình hiện thời của đối tượng CurrentUICulture.

Đa số các phương thức định dạng chuỗi đều thực hiện tốt với tiến trình của đối tượng CurrentUICulture có nghĩa là nó sẽ hiển thị chuẩn các thông tin như ngày tháng, con số, và tiền tệ trên giao diện người dùng ứng với Culture hiện hành của UI.

Ta hoàn toàn có thể sử dụng tài nguyên ở cấp độ trang với ASP.NET 2.0 trở lên bằng việc xây dựng tài nguyên cho trang cụ thể bên cạnh tài nguyên toàn cục (global resource)

Ta có thể gắn kết một điều khiển phía máy chủ với các chuỗi tài nguyên bằng việc sử dụng cú pháp sau <asp:Label runat="server" Text="<%$ resources: YourDateOfBirth %>"/>

Page 101: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

95

Lớp Cultural Information

Phương thức Miêu tả

CurrentCulture Trả về một đối tượng CultureInfo cung cấp thông tin về văn hóa được sử dụng trong tiến trình hiện hành

CurrentUICulture Trả về một đối tượng CultureInfo cung cấp thông tin về văn hóa được sử dụng bởi trình quản lí tài nguyên của hệ thống

DateTimeFormat Cung cấp cho bạn đối tượng DateTimeFormatInfo văn hóa cụ thể

InstalledUICulture Trả về một đối tượng CultureInfo cung cấp thông tin văn hóa trên hệ điều hành được cài đặt ở máy chủ

NumberFormat Cung cấp cho bạn đối tượng NumberFormatInfo như vậy bạn sẽ có các con số, tiền tệ, và phần trăm ứng với một văn hóa cụ thể

8.2.2. Xây dựng các tệp tài nguyên

Trong hệ thống siêu thị trực tuyến ta sẽ chỉ xây dựng 3 tệp tài nguyên toàn cục (global resouce files) và 2 tệp tài nguyên cục bộ (local resource files). Mỗi một tệp trong số 3 tệp tương ứng sẽ có một tệp dành cho các thông tin bằng tiếng Anh còn lại là bằng tiếng Việt và một tệp dành cho tiếng Ý. Mỗi một tệp sẽ cung cấp thông tin văn hóa tương ứng như đơn vị tiền tệ,đơn vị phần trăm, cách viết ngày tháng Tạo thư mục App_GlobalResources và trong thư mục này ta sẽ tạo 3 tệp tài nguyên là Message.resx, Message.it-IT.resx và tệp Message.vn-Vn.resx. Việc tạo 3 tệp hết sức đơn giản như hình sau:

Hình 3.29 – Tệp Message.resx

Hình 3.30 – Tệp Message.vn-VN.resx

Page 102: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

96

Hình 3.31 – Tệp Message.it-IT.resx Tạo thư mục localization trong thư mục View,rồi tạo thư mục App_LocalResources trong thư mục localization. Trong thư mục mới tạo này ta sẽ tạo 3 tệp tài nguyên là TestLocalization.resx, TestLocalization.it-IT.resx, Test.Localization.vn-Ve.resx. Việc tạo các tệp các tệp này cũng giống như các tệp trên và được thể hiện như hình vẽ dưới:

Hình 3.32 – Tệp TestLocalization.resx

Hình 3.33– Tệp TestLocalization.vn-VN.resx

Hình 3.34 – Tệp TestLocalization.it-IT.resx Ghi chú: Vậy là ta đã có đủ dữ liệu để xây dựng thử nghiệm module quốc tế hóa

Page 103: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

97

8.2.3. Controller của module

Trong thư mục Controller tạo tệp chứa với tên là LocalizationController.cs chứa controller mới của module. Controller này cho phép ta thiết lập văn hóa hiện hành của một tiến trình dựa trên thông tin trong hồ sơ người dùng và định dạng một vài kiểu thông tin theo định dạng tương ứng của văn hóa hiện hành đó: namespace GlobalStore.Controllers { [HandleError] public class LocalizationController : Controller { public ActionResult TestLocalization() {

Thread.CurrentThread.CurrentCulture = new CultureInfo(HttpContext.Profile.GetPropertyValue("Language") +

"-" +

HttpContext.Profile.GetPropertyValue("ContactInformation.Country"), false); Decimal amount = new Decimal(5);

ViewData["CurrencyExample"] = String.Format(CultureInfo.CurrentCulture.NumberFormat, "{0:c}", amount); ViewData["PercentageExample"] = String.Format(CultureInfo.CurrentCulture.NumberFormat, "{0:p}", amount); ViewData["NumberExample"] = String.Format(CultureInfo.CurrentCulture.NumberFormat, "{0:N}", amount); ViewData["DateExample"] = Convert.ToDateTime(DateTime.Now, CultureInfo.CurrentCulture.DateTimeFormat);

return View("TestLocalization"); } } }

8.2.4. View tƣơng ứng của module

Để tạo view cho module quốc tế hóa có tính minh họa ta sẽ không cần tạo quá nhiều thông tin mà chỉ cần các thông tin như tiền địa phương, cách viết con số của địa phương, cách viết phần trăm của địa phương, cách viết ngày và thời gian địa phương.. Tạo tệp TestLocalization.aspx trong thư mục Views/Localization như sau: <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"

Page 104: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

98

Inherits="System.Web.Mvc.ViewPage" culture="auto" meta:resourcekey="PageResource1" uiculture="auto" %> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h1><%= HttpContext.GetLocalResourceObject("~/Views/Localization/TestLocalization", "Title", System.Globalization.CultureInfo.CurrentUICulture)%></h1> <h3><%= HttpContext.GetGlobalResourceObject("Messages", "LocalGreeting", System.Globalization.CultureInfo.CurrentUICulture)%></h3> <p><%= HttpContext.GetLocalResourceObject("~/Views/Localization/TestLocalization", "Message", System.Globalization.CultureInfo.CurrentUICulture)%></p> <p><b>Localized Currency:</b> <%= ViewData["CurrencyExample"] %></p> <p><b>Localized Numbers:</b> <%= ViewData["NumberExample"] %></p> <p><b>Localized Percentages:</b> <%= ViewData["PercentageExample"] %></p> <p><b>Localized Date & Time:</b> <%= ViewData["DateExample"] %></p> <p><b><%= HttpContext.GetLocalResourceObject("~/Views/Localization/TestLocalization", "Copywrite", System.Globalization.CultureInfo.CurrentUICulture)%></b></p> </asp:Content>

Page 105: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

99

9. MODULE KIỂM THỬ

9.1. Tổng quan về module

Việc kiểm soát mã lệnh theo từng phần bộ phận tách biệt luôn là mong muốn của lập trình viên. Với ứng dụng ASP.NET việc thực hiện Unitest là hầu như không thể. Tuy nhiên thực hiện Unit test với ứng dụng ASP.NET MVC lại dễ dàng và dự án xây dựng với công nghệ .NET MVC có thể kiểm tra được toàn bộ. Tuy nhiên với ứng dụng siêu thị trực tuyến ta chỉ thực hiện kiểm thử với module bài báo, tin tức và blog, và module gửi thư.

9.2. Code cho module

Với module Bài báo, Tin tức, và Blog ta sẽ kiểm thử với phương thức hành động Index (xem tất cả các bài báo có trong hệ thống), CategoryIndex (xem tất cả các đầu mục báo) :

- Kiểm thử Index :

[TestMethod] public void IndexTest() { ArticleController target = new ArticleController(); ActionResult actual = target.Index("", 0); Assert.IsNotNull(actual); Assert.IsInstanceOfType(actual, typeof(ViewResult)); ViewResult viewResult = actual as ViewResult; Assert.IsNotNull(viewResult.ViewData); Assert.AreEqual("All Articles", viewResult.ViewData["PageTitle"]); var model = viewResult.ViewData.Model as IEnumerable<Article>; Assert.IsNotNull(model); }

- Kiểm thử Category Index:

[TestMethod] public void CategoryIndexTest() { ArticleController target = new ArticleController(); ActionResult actual = target.CategoryIndex(); Assert.IsNotNull(actual);

Page 106: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

100

Assert.IsInstanceOfType(actual, typeof(ViewResult)); ViewResult viewResult = actual as ViewResult; Assert.IsNotNull(viewResult.ViewData); Assert.AreEqual("All Categories", viewResult.ViewData["PageTitle"]);

var model = viewResult.ViewData.Model as IOrderedQueryable<Category>;

Assert.IsNotNull(model); } Với Module gửi thư ta cũng kiểm thử với phương thức hành động Index của module này và kiểm thử với phương thức hành động ManageNewsleters() trong lớp NewsletterController:

- Kiểm thử với Index: [TestMethod]

public void IndexTest() { NewsletterController target = new NewsletterController(); ActionResult actual = target.Index(); Assert.IsNotNull(actual); Assert.IsInstanceOfType(actual, typeof(ViewResult)); ViewResult viewResult = actual as ViewResult; Assert.IsNotNull(viewResult.ViewData);

Assert.AreEqual("Newsletters", viewResult.ViewData["PageTitle"]);

}

- Kiểm thử với ManageNewsletters: [TestMethod] public void ManageNewslettersTest() { NewsletterController target = new NewsletterController(); ActionResult actual = target.ManageNewsletters(); Assert.IsNotNull(actual); Assert.IsInstanceOfType(actual, typeof(ViewResult)); ViewResult viewResult = actual as ViewResult; Assert.IsNotNull(viewResult.ViewData);

Assert.AreEqual("Manage Newsletters", viewResult.ViewData["PageTitle"]);

var model = viewResult.ViewData.Model as IOrderedQueryable<Newsletter>;

Assert.IsNotNull(model);}

Page 107: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

101

CHƢƠNG 4: SỬ DỤNG WEB FORMS TRONG ỨNG DỤNG

ASP.NET MVC

1. TỔNG QUAN VỀ VIỆC KẾT HỢP CÔNG NGHỆ ASP.NET

MVC VÀ WEBFORMS TRONG CÙNG MỘT ỨNG DỤNG

1.1. Các lí do cho sự kết hợp giữa 2 công nghệ

Có 2 trường hợp thường xảy ra nhất khi ta có mong muốn kết hợp 2 công nghệ xây dựng ứng dụng nền tảng web vào một ứng dụng đó là: 1. Xây dựng ứng dụng MVC nhưng lại muốn sử dụng công nghệ WebForms trong

ứng dụng đó: Có thể bạn muốn tận dụng các trang WebForms,các web control, hay các control người dùng từ các dự án trước đó mà không có đủ thời gian để xây dựng lại tất cả từ đầu sử dụng công nghệ .NET MVC

2. Bạn có một ứng dụng WebForms đã hoàn thiện và muốn nâng cấp ứng dụng đó để hỗ trợ công nghệ MVC.

1.2. Tại sao có thể thực hiện đƣợc sự kết hợp này

Kết hợp ASP.NET webforms and ASP.NET MVC vào một ứng dụng là hoàn toàn có thể và thực tế là việc này khá dễ dàng. Lí do là ASP.NET MVC framework được xây dựng dựa trên chính ASP.NET. Thực tế là chỉ có một khác biệt duy nhất đáng quan tâm đó là toàn bộ công nghệ ASP.NET thì gói gọn trong System.Web trong khi ASP.NET MVC thì ngoài nằm trong System.Web nó còn nằm ở System.Web.Routing, System.Web.Abstractions, và System.Web.MVC. Điều này có nghĩa là nếu ta thêm 3 thư viện này vào ứng dụng ASP.NET thì ta có thể kết hợp giữa 2 công nghệ. Với ứng dụng ASP.NET MVC ta có thể trực tiếp thêm các trang webforms vào điều duy nhất ta phải làm là thiết lập thêm định tuyến cho các trang webforms để ASP.NET MVC định tuyến tới các tệp .aspx này.

1.3. Các bƣớc để kết hợp các trang WebForms vào ứng dụng

ASP.NET MVC

Trong chuyên đề này tôi sẽ xây dựng module Store Locator theo công nghệ

ASP.NET để minh họa cho việc kết hợp trang WebForms vào ứng dụng ASP.NET

MVC.

Để thực hiện được trước tiên tôi sẽ xây dựng các trang webforms của module

trong thư mục WebForms sau đó thêm định tuyến cho các trang này vào tệp

Global.asxc.

Page 108: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

102

uc Store Locator

Administrator

(from Actors)

User

(from Actors)

Locate Stores Add new store

2. MODULE TÌM CỬA HÀNG GẦN NHẤT

2.1. Tổng quan về module

Công ty GLOBAL STORE có các chuỗi cửa hàng ở khắp nơi trên thế giới. Các khách hàng khi mua hàng của Global Store họ thường có nhu cầu tìm cửa hàng gần nơi họ ở nhất theo khoảng cách cho trước là 5, 10,15,20,30,40,50 dặm. Việc tìm kiếm này được thực hiện thông qua module store locator. Trong dự án GLOBAL STORE trực tuyến này CSDL dành cho module store locator sử dụng địa chỉ các cửa hàng bất kì làm ví dụ minh họa. Địa chỉ cửa hàng mới được thêm vào bởi người dùng có vai trò quản trị .

2.2. Sơ đồ chức năng

Hệ thống có 2 chức năng như trong phân tích. Một là chức năng tìm kiếm cửa hàng gần nhất dành cho mọi người dùng, một là thêm địa chỉ cửa hàng mới chỉ dành cho người dùng có vai trò quản trị.

Hình 4.1 – Sơ đồ chức năng của module Store Locator

2.3. Phân tích cách xây dựng chức năng

Với chức năng tìm kiếm vị trị cửa hàng gần nhất: - Thông tin đầu vào: Địa chỉ (ở dạng đầy đủ và mã gửi thư – zip code) mà

qua đó người dùng muốn tìm các cửa hàng gần địa điểm (của địa chỉ đó) trong bán kính là một trong các lựa chọn 5, 10,15,20,30,40,50 dặm

- Kết quả : Hiển thị địa chỉ các cửa hàng nằm trong bán kính đó theo thứ tự về khoảng cách, hiển thị bản đồ Google với các Marker đánh dấu các vị trí tìm được trên bản đồ…

ta sẽ phải thực hiện được những việc sau:

- Xác định được (latitude, longtitude) của vị trí từ địa chỉ có được ở ô dành cho việc điền địa chỉ.

- Tính được khoảng cách của các cửa hàng có trong CSDL tới địa điểm của địa chỉ đó từ đó chọn ra các cửa hàng gần địa điểm đó trong bán kính yêu cầu.

Page 109: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

103

- Hiển thị kết quả tìm được. Với chức năng thêm cửa hàng mới :

- Thông tin đầu vào : Tên cửa hàng, địa chỉ đầy đủ, tên thành phố, tên bang, mã gửi thư.

- Kết quả đầu ra: lưu toàn bộ thông tin về cửa hàng vào CSDL gồm các thông tin đầu vào và cả thông tin longitude, latitude. Trong trường hợp địa chỉ cửa hàng không xác định hệ thống sẽ đưa ra thông báo cho người dùng.

Ta sẽ phải thực hiện việc:

- Qua Google map api tìm được (longtitude, latitude) của cửa hàng thông qua các thông tin đầu vào.

- Thực hiện việc lưu thông tin xuống CSDL.

2.4. Bảng CSDL

Theo phân tích chức năng thì ta cần một bảng Location để lưu thông tin vị trí của cửa hàng :

Hình 4.2 – Bảng Locations Thủ tục GetNearByLocations: Tính toán và lọc ra các cửa hàng gần người dùng nhất. Thủ tục InsertLocation: Chèn một vị trí mới vào bảng Locations 3 hàm XAxis, YAxis, và ZAxis, được dùng dành cho việc tính toán của thủ tục GetNearByLocations.

Page 110: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

104

2.5. Các lớp hỗ trợ trong module

Trong chức năng tìm kiếm các cửa hàng gần nhất cũng như chức năng thêm cửa hàng vào CSDL việc xác định ta đều cần thông tin (Latitude, Longtitude ) của địa chỉ người dùng nhập và cả 2 thông tin đó đều cần thiết cho việc tính toán khoảng cách của thủ tục GetNearByLocations cũng như cần thiết cho việc hiển thị Marker trên bản đồ Google vậy để xác định được ta phải sử dụng Google Map API và xây dựng lớp GeoCode như sau: namespace GoogleGeocoder { public interface ISpatialCoordinate { decimal Latitude { get; set; } decimal Longitude { get; set; } } /// <summary> /// Coordiate structure. Holds Latitude and Longitude. /// </summary> public struct Coordinate : ISpatialCoordinate { private decimal _latitude; private decimal _longitude; public Coordinate(decimal latitude, decimal longitude) { _latitude = latitude; _longitude = longitude; } #region ISpatialCoordinate Members public decimal Latitude { get { return _latitude; } set { this._latitude = value; } } public decimal Longitude { get { return _longitude;

Page 111: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

105

} set { this._longitude = value; } } #endregion } public class Geocode { private const string _googleUri = "http://maps.google.com/maps/geo?q="; private const string _outputType = "csv"; // Available options: csv, xml, kml, json /// <summary> /// Returns a Uri of the Google code Geocoding Uri. /// </summary> /// <param name="address">The address to get the geocode for.</param> /// <returns>A new Uri</returns> private static Uri GetGeocodeUri(string address) { string googleKey = ConfigurationManager.AppSettings["googleApiKey"].ToString(); address = HttpUtility.UrlEncode(address); return new Uri(String.Format("{0}{1}&output={2}&key={3}", _googleUri, address, _outputType, googleKey)); } /// <summary> /// Gets a Coordinate from a address. /// </summary> /// <param name="address">An address. /// <remarks> /// <example> /// 3276 Westchester Ave, Bronx, NY 10461 /// /// or /// /// New York, NY /// /// or /// /// 10461 (zipcode) /// </example> /// </remarks>

Page 112: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

106

/// </param> /// <returns>A spatial coordinate that contains the latitude and longitude of the address.</returns> public static Coordinate GetCoordinates(string address) { WebClient client = new WebClient(); Uri uri = GetGeocodeUri(address); /* The first number is the status code, * the second is the accuracy, * the third is the latitude, * the fourth one is the longitude. */ string[] geocodeInfo = client.DownloadString(uri).Split(','); return new Coordinate(Convert.ToDecimal(geocodeInfo[2]), Convert.ToDecimal(geocodeInfo[3])); } } }

Và trước khi tìm địa chỉ các cửa hàng gần nhất ta sẽ gọi tới hàm GetCoorDinates trong lớp Geocode để lấy Latitude và Longtitude của địa chỉ người dùng nhập vào như sau: //Get the coordinate of the address Coordinate coordinate = Geocode.GetCoordinates(addressTextBox.Text);

Ngoài ra ta sẽ phải xây dựng DataSet cho việc chứa các địa chỉ cửa hàng tìm được gần địa chỉ mà khách hàng nhập vào nhất gồm 2 tệp một tệp chứa design của DataSet là LocationsData.xsd ,một tệp chứa code LocationsData.Designer.cs Hình 4.3 – Tệp LocationsData.xsd

Page 113: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

107

2.6. View

Module này có 2 view một dành cho mọi người dùng tìm kiếm siêu thị gần họ nhất, view còn lại chỉ dành cho người dùng có vai trò quản trị để thêm vị trí cửa hàng mới

Tên trang Đặc tả Đường dẫn ảo StoreLocator.aspx Trang này cho

phép người dùng tìm kiếm siêu thị gần họ nhất

Locator/Index

AddStoreLocation.aspx Trang này dành cho người dùng với vai trò quản trị thêm vị trí cửa hàng mới vào CSDL

Locator/AddStore

2.7. Thêm định tuyến cho các trang view của module

Khi mà ta yêu cầu một trang web sử dụng Url tương ứng với trang đó trên ổ đĩa tức là ta đã hoàn toàn tránh không sử dụng hệ thống định tuyến của ASP.NET MVC. Tuy nhiên trong module này ta muốn yêu cầu trang web StoreLocator.aspx và AddStoreLocation.aspx thông qua hệ thống định tuyến đó bằng cách sử dụng phương pháp: Tạo phương thức sinh URL hướng tới thư mục nằm ngoài thư mục Views. Cụ thể thư mục đó là WebForms. Đây là đoạn code của lớp chứa phương thức đó: //Create route class for WebForms public class WebFormsRoute : Route { //Constructor is hard-coded to use the special WebFormsRouteHandler public WebFormsRoute(string url, string virtualPath) : base(url, new WebFormsRouteHandler { VirtualPath = virtualPath }) { } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { //Only generate outbound URL when "virtual Path" matches this entry string path = ((WebFormsRouteHandler)this.RouteHandler).VirtualPath;

Page 114: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

108

if ((string)values["VirtualPath"] != path) return null; else { // var valuesExceptVirtualPath = new RouteValueDictionary (values); valuesExceptVirtualPath.Remove("virtualPath"); return base.GetVirtualPath(requestContext, valuesExceptVirtualPath); } } private class WebFormsRouteHandler : IRouteHandler { public string VirtualPath { get; set; } //Compiles the ASPX file if needed and instantiates the web form public IHttpHandler GetHttpHandler(RequestContext requestContext) { return (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(IHttpHandler)); } } } Ở đây ta đã sử dụng tới lớp BuildManager để định vị, dịch và tạo thể hiện của các trang webforms. Với lớp này ta có thể tạo ngay định tuyến cho các tệp StoreLocator.aspx và AddStoreLocation.aspx trong thư mục WebForms và thêm các định tuyến này vào bảng định tuyến: #region Locator

routes.Add(new WebFormsRoute("Locator/Index", "~/WebForms/StoreLocator.aspx")); routes.Add(new WebFormsRoute("Locator/AddStore", "~/WebForms/AddStoreLocation.aspx"));

#endregion

2.8. Vấn đề bảo mật

Một vấn đề ở đây là chúng ta cần thêm luật xác thực cho định tuyến Urls mới tạo để bảo vệ các trang khỏi kiểu truy cập trực tiếp sử dụng định tuyến đó: <!-- Configuration Extension For Preventing Direct Access To Web Form Pages-->

Page 115: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

TIÊU ĐỀ CHƢƠNG 3

109

<location path="Locator/AddNewStore"> <system.web> <authorization> <allow roles="Admin"/> <deny users="*"/> </authorization> </system.web> </location> <location path="WebForms/AddStoreLocation.aspx"> <system.web> <authorization> <deny users="*"/> </authorization> </system.web> </location>

Page 116: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

110

CHƢƠNG 5: TRIỂN KHAI ỨNG DỤNG VÀ HƢỚNG PHÁT

TRIỂN

1. TRIỂN KHAI ỨNG DỤNG

1.1. Các bƣớc triển khai

Công việc triển khai được chia làm 2 bước: Triển khai cơ sở dữ liệu và triển khai gobal store site. Về phần CSDL do IIS hỗ SQL server express cho nên CSDL này sẽ được gắn với ứng dụng GlobalStore khi ta triển khai ứng dụng này. Ở đây GlobalStore site chỉ sử dụng như là một site nhỏ nên ta chỉ cần dùng SQL server express để chứa CSDL.

1.2. Triển khai Global Store Site

Ta sẽ thực hiện triển khai Global Store Site với chức năng Public từ Visual Studio

như hình dưới đây sau khi chạy Visual Studio với vai trò administrator:

Hình 5.1 – Triển khai Global Store Site

Page 117: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

111

1.3. Cấu hình IIS 7.0 cho Framework MVC sử dụng Microsoft

Web Platform Installer

Công cụ cài đặt Web Platform này là một công cụ mới của Microsoft hỗ trợ cài đặt trọn bộ Web Platform của Microsoft. Sau khi cài công cụ này khởi động nó ta sẽ thấy trên màn hình :

Hình 5.2 – Màn hình chọn lựa Paltform để cài đặt

Page 118: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

112

Ta phải đảm bảo rằng .NET framework và ASP.NET MVC mới nhất được cài đặt bằng cách nhấn vào link Customize mục Framworks and Runtimes như hình dưới đây nếu đã có dấu tích chìm ứng với các mục cần cài thì tức là chúng đã được cài đặt vào máy.

Hình 5.3 – Màn hình kiêm tra các cài đặt của .NET Framework và ASP.NET MVC

Page 119: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

113

Kiểm tra xem đã cài SQL Server express 2008 chưa bằng việc chọn liên kết Customize ở mục Database nếu như có dấu tích chìm ở phần SQL Server Express 2008 ở màn hình mới mở ra thì tức là SQL server express 2008 đã được cài đặt.

Hình 5.4 – Màn hình kiểm tra việc cài đặt SQL server express 2008

1.4. Thêm Global Store site vào IIS 7.0

Chạy máy chủ quản lí thông tin Internet của Microsoft – IIS 7.0 như trong hình vẽ

Hình 5.5 – IIS Manager

Page 120: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

114

Nhấn vào node của máy chủ rồi nhấn chuột phải chọn Add Web Site ta sẽ thấy màn hình như sau

Hình 5.6 – Add Web Site Dialog Ở đây sẽ cần một số các thiết lập như đặt tên cho site, gán Host header …

Page 121: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

115

2. Hƣớng phát triển ứng dụng

Do thời gian và phạm vi làm chuyên đề tốt nghiệp cũng như hiểu biết còn hạn chế nên em đã chỉ có thể đa phần là áp dụng những kĩ thuật cơ bản trong lập trình ứng dụng nền tảng web sử dụng công nghệ .NET MVC và ASP.NET của Microsft. Trên thực tế hệ thống còn có thể mở rộng theo một số hướng như sau để trở nên hữu ích và hiệu quả hơn.

2.1. Hỗ trợ tìm kiếm sản phẩm mở rộng

Với một hệ thống lớn như Global Store việc xây dựng chức năng tìm kiếm sản phẩm mở rộng là cần thiết giúp khách hàng tiết kiệm được thời gian tìm kiếm cũng như khiến cho hệ thống trở nên hữu ích hơn.

2.2. Mở rộng chức năng tìm kiếm cửa hàng gần nhất

Việc tìm kiếm cửa hàng gần nhất là một tiện ích khá thú vị của hệ thống tuy nhiên mục tiêu cần hướng tới là trong trường hợp khách hàng có lựa chọn sản phẩm vào giỏ hàng thì hệ thống cần thiết phải thông báo cho khách hàng biết sản phẩm mà khách hàng muốn mua đó có hay không có ở các siêu thị mà họ định tới. Ngoài ra cũng cần có các thông tin bổ trợ về siêu thị như giờ mở cửa, giờ đóng cửa ,…

2.3. Xây dựng module báo cáo tình hình bán hàng của siêu thị kết

xuất ra các tệp định dạng Execel, Pdf

Đây là một module khá cần thiết cho một ứng dụng kiểu như siêu thị trực tuyến, ông chủ của Global Store Pte luôn có nhu cầu nắm bắt các thông tin bán hàng của từng siêu thị. Để xây dựng được module này ở mức cao như yêu cầu thực tế của những site như www.bestbuy.com hay www.walmart.com không phải là điều dễ dàng xong xây dựng để mô phỏng thì không khó và là cần thiết.

Page 122: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

116

KẾT LUẬN

Sau khi thực hiện xong chuyên đề tốt nghiệp xây dựng hệ thống siêu thị trực tuyến

em đã tìm hiểu được một số công nghệ xây dựng ứng dụng nền tảng web của

Microsoft:

- ASP.NET MVC

- ASP.NET

Tìm hiểu và ứng dụng cách kết hợp 2 công nghệ xây dựng ứng dụng web của

Microsoft là ASP.NET MVC và ASP.NET

Tìm hiểu và sử dụng các webservices sử dụng trong chức năng thanh toán với

Paypal, hay chức năng hiển thị bản đồ Google của module định vị cửa hàng gần

nhất.

Tìm hiểu và sử dụng AJAX cho các hành động phía Client, kĩ thuật xây dựng bộ

nhớ đệm,…

Page 123: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

117

TÀI LIỆU THAM KHẢO

Tiếng Anh:

Về chức năng tham khảo các trang http://www.walmart.com/,

http://www.bestbuy.com/

ScottGu (5/2007), Using LINQ to SQL, xem trên blog của ScottGu

(http://weblogs.asp.net/scottgu)

How to use Membership in ASP.NET 2.0, trong msdn của microsoft

http://msdn.microsoft.com/en-us / library/ ff648345.aspx#paght000022

_sqlmembershipproviderconfig )

Troy Mageniss (2010), LINQ to Object using C# 4.0, Chapter 3,4

ASP.NET MVC, các bài từ cơ bản đến nâng cao về framework asp.net mvc trên

trang dành cho .NET MVC của microsoft (http://www.asp.net/mvc/fundamentals)

Steven Sanderson (2009), Pro ASP.NET MVC framework, p540 tới p546 –

Internationlization, p555 tới p576 commbination of ASP.NET and ASP.NET MVC

technology in one application.

Bear Bibfault, (11/2008), JQuery in action, Chapter 8 Talk to the server with Ajax

p217 tới p266.

Google developers, Google map API, xem ở (http://code.google.com/apis/maps/)

Paypal developers, Paypal API, xem ở (https://cms.paypal.com/us/cgi-

bin/?cmd=_render-content&content_ID=developer/howto_api_reference )

Page 124: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

118

DANH MỤC HÌNH ẢNH

Hình 1.1 – Kiến trúc ứng dụng – Trang 6

Hình 1.2 - Mối quan hệ giữa các tầng giao diện, logic nghiệp vụ, truy cập CSDL và

lưu trữ CSDL – Trang 8

Hình 2.1 – Mô hình MVC cơ bản – Trang 13

Hình 2.2 – Mô hình xử lí yêu cầu từ ứng dụng ASP.NET MVC – Trang 17

Hình 2.3 – Mô hình LINQ to SQL – Trang 18

Hình 2.4 – Mô hình NorthwindDataContext – Trang 20

Hình 2.5 – Hình minh họa lấy sản phẩm từ CSDL với LINQ - Trang 20

Hình 2.6 – Hình minh họa cập nhật sản phẩm từ CSDL với LINQ – Trang 20

Hình 2.7 – Chèn sản phẩm mới vào CSDL – Trang 21

Hình 2.7 – Xóa một sản phẩm – Trang 21

Hình 2.8 – Gọi một thủ tục – Trang 22

Hình 2.9 – Lấy các sản phẩm và phân trang – Trang 22

Hình 3.1 – Các module của hệ thống siêu thị trực tuyến – Trang 23

Hình 3.2 – Sơ đồ tổng quan chức năng của module theo mô hình UC – Trang 26

Hình 3.3 – Tạo CSDL cho module hồ sơ và người dùng – Trang 27

Hình 3.4 Bảng Langugage – Trang 27

Hình 3.5 Sơ đồ lớp UserInformation – Trang 29

Hình 3.6 Sơ đồ lớp ProfileInformation – Trang 30 Hình 3.7 Sơ đồ chức năng theo mô hình UC của module thương mại – Trang 35 Hình 3.8 – Các tài khoản kiểm thử với sandbox – Trang 36 Hình 3.9 Sơ đồ quan hệ các bảng dữ liệu trong module thương mại – Trang 38 Hình 3.10 – Sơ đồ các lớp thực thể LINQ-to-SQL của module – Trang 39 Hình 3.11 – Các lớp xây dựng thêm hỗ trợ cho module – Trang 40 Hình 3.12 – Sơ đồ chức năng của module - Trang 53 Hình 3.13 – Bảng Newsletters – Trang 53 Hình 3.14 – Sơ đồ Model Newsletter – Trang 55

Page 125: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

DANH MỤC HÌNH ẢNH

119

Hình 3.15 – Sơ đồ chức năng của module lấy ý kiến người dùng – Trang 57 Hình 3.16 – Sơ đồ mối quan hệ giữa 2 bảng DL của module lấy ý kiến người dùng – Trang 58 Hình 3.17 – Sơ đồ thiết kế bảng PollOptions – Trang 58 Hình 3.18 – Sơ đồ thiết kế bảng Polls – Trang 59 Hình 3.19 – Sơ đồ lớp PollOption và Poll – Trang 60 Hình 3.20 – Sơ đồ lớp PollQueries – Trang 60 Hình 3.21 – Sơ đồ chức năng module Forum – Trang 68 Hình 3.22 – Các bảng dữ liệu của module forum – Trang 69 Hình 3.23 – Sơ đồ các lớp thực thể LINQ-to-SQL Post, Forum, Vote – Trang 70 Hình 3.24 – Sơ đồ lớp ForumQueries – Trang 70 Hình 3.25 – Sơ đồ chức năng của module bài báo, tin tức, và blog – Trang 79 Hình 3.26 – Sơ đồ bảng Categories, Comments, Articles và quan hệ của chúng – Trang 79 Hình 3.27 – Sơ đồ các lớp thực thể Article, Comment, Category – Trang 80 Hình 3.28 – Sơ đồ các lớp mở rộng ArticlesQueries, Article, ArticleCollectionWrapper - Trang 82 Hình 3.29 – Tệp Message.resx – Trang 95 Hình 3.30 – Tệp Message.vn-VN.resx – Trang 95 Hình 3.31 – Tệp Message.it-IT.resx – Trang 96 Hình 3.32 – Tệp TestLocalization.resx – Trang 96 Hình 3.33 – Tệp TestLocalization.vn-VN.resx – Trang 96 Hình 3.34 – Tệp TestLocalization.it-IT.resx – Trang 96 Hình 4.1 – Sơ đồ chức năng của module Store Locator - Trang 102 Hình 4.2 – Bảng Locations – Trang 103 Hình 4.3 – Tệp LocationsData.xsd – Trang 106 Hình 5.1 – Triển khai Global Store Site – Trang 110

Page 126: CDTN Tim Hieu ASP NET MVC Va Xay Dung Sieu Thi Truc Tuyen Lan 3 29 Thang 5 Nam 2010

DANH MỤC HÌNH ẢNH

120

Hình 5.2 – Màn hình chọn lựa Paltform để cài đặt – Trang 111 Hình 5.3 – Màn hình kiêm tra các cài đặt của .NET Framework và ASP.NET MVC – Trang 112 Hình 5.4 – Màn hình kiểm tra việc cài đặt SQL server express 2008 – Trang 112 Hình 5.5 – IIS Manager – Trang 113 Hình 5.6 – Add Web Site Dialog – Trang 114