You are on page 1of 170

TRƯỜNG ĐẠI HỌC SƯ PHẠM KỸ THUẬT HƯNG YÊN

KHOA CÔNG NGHỆ THÔNG TIN

ĐỀ CƯƠNG

MÔN: LẬP TRÌNH WEB VỚI MÔ HÌNH MVC

Hưng Yên, tháng 8 năm 2019


MỤC LỤC
Bài 1. Tổng quan về MVC .............................................................5
1.1 Tổng quan về môn học ........................................................................................... 5

1.2 Giới thiệu về lập trình web ..................................................................................... 5

1.3 Một vài công nghệ lập trình web thông dụng ......................................................... 6

1.4 Lựa chọn công nghệ phát phát triển ....................................................................... 8

1.5 Các nền tảng lập trình web ..................................................................................... 8

1.6 Đưa một website lên mạng Internet ...................................................................... 11

Bài 2. Mô hình thiết kế website với MVC Framework .............11


2.1. Giới thiệu mô hình Asp.net MVC ....................................................................... 12

2.2. MVC và môi trường phát triển Visual Studio ..................................................... 13

2.3. Tạo ứng dụng MVC đầu tiên ............................................................................... 13

2.4. Tìm hiểu các thư mục, thư viện Visual Studio tự động sinh ............................... 14

2.5. Route và cấu hình route trong MVC ................................................................... 15

2.6. Route và SEO ...................................................................................................... 17

Bài 3. Các thành phần trong MVC .............................................18


3.1. Model................................................................................................................... 18

3.2. Controller............................................................................................................. 20

3.3. View .................................................................................................................... 21

3.4. Mô hình MVC không đầy đủ............................................................................... 24

Bài 4. Thảo luận 1 về mô hình lập trình MVC .. Error! Bookmark


not defined.

Bài 5. TH 1. Ứng dụng MVC căn bản ........................................24

Bài 6. Sử dụng EntityFramework trong MVC ..........................27


6.1. Giới thiệu về EntityFramework ........................................................................... 28

6.2. Tạo lớp Entity định nghĩa kết nối đến Cơ sở dữ liệu........................................... 29

1
6.3. Tạo chuỗi kết nối và khai báo dữ liệu mặc định .................................................. 30

6.4. Truyền dữ liệu Controller – View ....................................................................... 32

Bài 7. Lập trình MVC với Entity Framework ...........................34


7.1. Thao tác thêm – sửa – xóa dữ liệu dùng Entity Framework ................................ 35

7.2. Hiển thị dữ liệu .................................................................................................... 35

7.3. Thêm mới dữ liệu ................................................................................................ 37

7.4. Sửa dữ liệu........................................................................................................... 44

7.5. Dùng chung View Create và Edit ........................................................................ 47

7.6. Xóa dữ liệu .......................................................................................................... 50

7.7. Xem chi tiết dữ liệu ............................................................................................. 52

7.8. Một vài vấn đề phát sinh trong xử lý CRUDs ..................................................... 53

Bài 8. Thảo luận 2 về kết nối dữ liệu với Entity ........................54


Bài 9. TH 2 Tạo và kết nối cơ sở dữ liệu sử dụng Entity ..........55

Bài 10. Thao tác với cơ sở dữ liệu trong MVC ..........................55


10.1. Tương tác dữ liệu từ Controller sang View ....................................................... 57

10.2. Post dữ liệu dùng Model – View Model............................................................ 61

10.2.1 Post dữ liệu dùng Model.................................................................................. 64

10.2.1 Post dữ liệu dùng View Model ........................................................................ 66

10.2.1 Controller......................................................................................................... 67

10.3. Post dữ liệu dùng tên thẻ input .......................................................................... 67

10.4. Post dữ liệu dùng FormCollection ..................................................................... 68

Bài 11. Tạo liên kết cơ sở dữ liệu với Emtity Framework ........68
11.1. Bảng dữ liệu chứa quan hệ trong EF code first ................................................. 69

11.2. Tạo dữ liệu thao tác với Entity Framework ....................................................... 70

Bài 12. TH 3. Truyền dữ liệu giữa các thành phần của MVC .74

Bài 13. Giới thiệu Razor View Engine ........................................78


2
13.1. Lớp SelectListItem và SelectList ...................................................................... 79

13.2. Dùng lớp SelectList tạo nguồn dữ liệu Dropdowlist trong MVC...................... 79

13.3. Các khái niện cơ bản về Razor .......................................................................... 82

13.4. Viết mã Razor .................................................................................................... 82

13.5. Html Helper Control .......................................................................................... 83

13.6. ActionLink......................................................................................................... 84

13.7. Đối tượng Helpers và Functions trong Razor code ........................................... 85

Bài 14. Import nội dung trong Razor code ................................95


14.1. Html.Partial ....................................................................................................... 96

14.2. RenderPartial ..................................................................................................... 97

14.3. Html.PartialView:.............................................................................................. 97

14.4. Html.Action và Html.RenderAction.................................................................. 97

14.5. RenderBody, RenderPage, RenderSection ........................................................ 99

Bài 15. Thảo luận 3 các trình điều khiển trên MVC ...............100
Bài 16. TH 4. Sử dụng điều khiển trong MVC ........................101

Bài 17. Sử dụng Layout ..............................................................112


17.1. Giới thiệu Layout trong MVC ......................................................................... 113

17.2. Xử lý layout trong MVC ................................................................................. 114

17.3. Khái niệm attribute .......................................................................................... 118

17.4. Sử dụng CkEditor Template ............................................................................ 119

Bài 18. TH 5. Xây dựng trang MasterPage ..............................123

Bài 19. Thảo luận 4 Xây dựng giao diện website sử dụng
Template ......................................................................................125

Bài 20. Biến trạng thái trong MVC ..........................................128


20.1. Cookie ............................................................................................................. 128

20.2. Session ............................................................................................................. 130

3
Bài 21. Bảo mật – phân quyền trong ứng dụng MVC ............132
21.1. Tạo Controller kiểm tra đăng nhập .................................................................. 133

21.2. Bảo vệ Action – Controller tránh truy xuất ..................................................... 136

21.3. Phân quyền truy cập ........................................................................................ 138

21.4. Tạo Provider riêng để phân quyền truy cập Action ......................................... 140

Bài 22. TH 6 Sử dụng biến trạng thái trong MVC ..................144

Bài 23. Javascript jQuery CSS ..................................................146


23.1. Sử dụng CSS định dạng Layout ...................................................................... 147

23.2. Sử dụng CSS định dạng các trang kế thừa ...................................................... 150

23.3. Sử dụng Javascript jQuery............................................................................... 151

23.4. Sử dụng jQuery trong lập trình Ajax ............................................................... 154

Bài 24. TH 7. Lập trình MVC với Json, Jquery ......................158

Bài 25. TH 8. Kiểm tra thực hành.............................................168

4
BÀI 1. TỔNG QUAN VỀ MVC
1.1 Tổng quan về môn học
Mẫu kiến trúc Model – View – Controller được sử dụng nhằm chi ứng dụng
thành ba thành phần chính: model, view và controller. Nền tảng ASP.NET MVC giúp
cho chúng ta có thể tạo được các ứng dụng web áp dụng mô hình MVC thay vì tạo ứng
dụng theo mẫu ASP.NET Web Forsm. Nền tảng ASP.NET MVC có đặc điểm nổi bật
là nhẹ (lighweigt), dễ kiểm thử phần giao diện (so với ứng dụng Web Forms), tích hợp
các tính năng có sẵn của ASP.NET. Nền tảng ASP.NET MVC được định nghĩa trong
namespace System.Web.Mvc và là một phần của name space System.Web.

MVC là một mẫu thiết kế (design pattern) chuẩn mà nhiều lập trình viên đã quen
thuộc. Một số loại ứng dụng web sẽ thích hợp với kiến trúc MVC. Một số khác vẫn
thích hợp với ASP.NET Web Forms và cơ chế postbacks. Đôi khi có những ứng dụng
kết hợp cả hai kiến trúc trên.

1.2 Giới thiệu về lập trình web


Models: Các đối tượng Models là một phần của ứng dụng, các đối tượng này
thiết lập logic của phần dữ liệu của ứng dụng. Thông thường, các đối tượng model lấy
và lưu trạng thái của model trong CSDL. Ví dụ như, một đối tượng Product (sản phẩm)
sẽ lấy dữ liệu từ CSDL, thao tác trên dữ liệu và sẽ cập nhật dữ liệu trở lại vào bảng
Products ở SQL Server.

Trong các ứng dụng nhỏ, model thường là chỉ là một khái niệm nhằm phân biệt
hơn là được cài đặt thực thụ, ví dụ, nếu ứng dụng chỉ đọc dữ liệu từ CSDL và gởi chúng
đến view, ứng dụng khong cần phải có tầng model và các lớp lien quan. Trong trường
hợp này, dữ liệu được lấy như là một đối tượng model (hơn là tầng model).

Views: Views là các thành phần dùng để hiển thị giao diện người dùng (UI).
Thông thường, view được tạo dựa vào thông tin dữ liệu model. Ví dụ như, view dùng
để cập nhật bảng Products sẽ hiển thị các hộp văn bản, drop-down list, và các check
box dựa trên trạng thái hiện tại của một đối tượng Product.

Controllers: Controller là các thành phần dùng để quản lý tương tác người dùng,
làm việc với model và chọn view để hiển thị giao diện người dùng. Trong một ứng dụng
MVC, view chỉ được dùng để hiển thị thông tin, controller chịu trách nhiệm quản lý và
đáp trả nội dung người dùng nhập và tương tác với người dùng. Ví dụ, controller sẽ
quản lý các dữ liệu người dùng gởi lên (query-string values) và gởi các giá trị đó đến
model, model sẽ lấy dữ liệu từ CSDL nhờ vào các giá trị này.

Mẫu MVC giúp bạn tạo được các ứng dụng mà chúng phân tách rạch ròi các
khía cạnh của ứng dụng (logic về nhập liệu, logic xử lý tác vụ và logic về giao diện).
Mẫu MVC chỉ ra mỗi loại logic kể trên nên được thiếp lập ở đâu trên ứng dụng. Logic
giao diện (UI logic) thuộc về views. Logic nhập liệu (input logic) thuộc về controller.
Và logic tác vụ (Business logic – là logic xử lý thông tin, mục đích chính của ứng dụng)
thuộc về model. Sự phân chia này giúp bạn giảm bớt được sự phức tạp của ứng dụng

5
và chỉ tập trung vào mỗi khía cạnh cần được cài đặt ở mỗi thời điểm. Ví dụ như bạn chỉ
cần tập trung vào giao diện (views) mà không phải quan tâm đến logic xử lý thông tin
của ứng dụng.

Để quản lý sự phức tạp của ứng dụng, mẫu MVC giúp cho chúng ta có thể kiểm
thử ứng dụng dễ dàng hơn hẳn so với khi áp dụng mẫu Web Forms. Ví dụ, trong một
ứng dụng ASP.NET Web Forms, một lớp thường được sử dụng để hiển thị thông tin
xuất ra cho người dùng và đồng thời xử lý thông tin người dùng nhập. Việc xây dựng
các bộ test tự động cho ứng dụng Web Forms là rất phức tạp, bởi để kiểm thử mỗi trang
web, bạn phải khởi tạo đối tượng trang, khởi tạo tất cả các control được sử dụng trong
trang và các lớp phụ thuộc trong ứng dụng. Và bởi vì có quá nhiều lớp cần được khởi
tạo để chạy được trang, thật khó để có thể viết các test chỉ tập trung vào một khía cạnh
nào đó của ứng dụng. Và vì thế, kiểm thử đối với các ứng dụng dứa trên nền tảng Web
Forms sẽ khó khăn hơn nhiều so với khi áp dụng trên ứng dụng MVC. Hơn thế nữa,
việc kiểm thử trên nền tảng Web Forms yêu cầu phải sử dụng đến web server. Nền tảng
MVC phân tách các thành phần và sử dụng các interface (khái niệm giao diện trong lập
trình hướng đối tượng), và nhờ đó có thể kiểm thử các thành phần riêng biệt trong tình
trạng phân lập với các yếu tố còn lại của ứng dụng.

Sự phân tách rạch ròi ba thành phần của ứng dụng MVC còn giúp cho việc lập
trình diễn ra song song. Ví dụ như một lập trình viên làm việc với view, lập trình viên
thứ hai lo cài đặt logic của controller và lập trình viên thứ ba có thể tập trung vào logic
tác vụ của model tại cùng một thời điểm.

1.3 Một vài công nghệ lập trình web thông dụng
Công nghệ Python

Python là tên gọi của một loại ngôn ngữ lập trình phổ biến, chạy trên nền tảng
MacOSX, Windows, Linux. Đây là loại ngôn ngữ lập trình có tính hướng đối tượng, dễ
học và có tính ứng dụng cao.

Ngôn ngữ Python không chỉ được ứng dụng trong ngành lập trình web, khoa
học tính toán số liệu mà còn được xem là nhân tố chính để tạo nguyên mẫu phần mềm,
tiêu biểu là các phần mềm game. Google, Microsoft và nhiều tập đoàn, công ty tin học
đã từng sử dụng để vận hành hệ thống dịch vụ của mình và đạt được nhiều thành công.

Công nghệ Java

Java cũng là một loại ngôn ngữ lập trình phổ biến có tính độc lập về nền tảng
và hướng đối tượng đầy đủ nhất. Loại ngôn ngữ này được hình thành và phát triển từ
những năm 1990 thế nhưng đến nay vẫn không hề giảm bớt sức“hot” bởi những ứng
dụng vừa gần gũi lại vừa quan trọng.

Ngôn ngữ này được ứng dụng khá nhiều, từ việc tạo các trang web thương mại
điện tử, khoa học đến các ứng dụng trong lĩnh vực giao dịch tài chính điện tử. Các ngân
hàng đầu tư toàn cầu như Goldman Sachs, Citigroup, Barclays, Standard Chartered đã
sử dụng Java để viết các hệ thống giao dịch điện tử, các hệ thống xác nhận và kiểm

6
toán, các dự án xử lý dữ liệu và một số công việc quan trọng khác. Ngoài các ứng dụng
trên Java còn được biết đến như một thành tố quan trọng để tạo nên các ứng dụng game,
ứng dụng destop…

Công nghệ JavaScript

JavaScript là ngôn ngữ lập trình kịch bản phía máy khách (client – side) duy
nhất được tạo ra vào năm 1995. Loại ngôn ngữ này có tính phổ biến và ứng dụng rất
cao, được sử dụng ở hầu hết các trang web trên internet tạo tính tương tác cao.

Cũng giống như Python, Java, JavaScript được ứng dụng để lập trình web, thiết
lập các ứng dụng trên điện thoại di động, ứng dụng trên destop và game. Ngoài ra các
slideshow, pop-up quảng cáo và tính năng autocomplete của Google cũng là những là
“tuyệt phẩm” được viết bằng ngôn ngữ lập trình JavaScript.

Công nghệ Big data

Big data là tập hợp dữ liệu có dung lượng vượt mức đảm đương của những ứng
dụng và công cụ truyền thống. Đây là công nghệ được hình từ năm 2001 và có nhiều
ứng dụng quan trọng.

Đối với doanh nghiệp: Nó giúp thu thập dữ liệu hành vi người dùng để các
doanh nghiệp đưa ra các giải pháp kinh doanh phù hợp với nhu cầu nhằm gia tăng lợi
nhuận. Các ứng dụng mua sắm trên EBay, Amazon… chính là sản phẩm của big data.
Software AG, Oracle, IBM, Microsoft, SAP, EMC, HP, Dell là những đơn vị đã đi đầu
trong việc ứng dụng công nghệ này.

Đối với các tổ chức phi chính phủ: Big data hỗ trợ rất nhiều cho các hoạt động
phân tích dữ liệu, dự đoán được tỉ lệ thất nghiệp, xu hướng nghề nghiệp của tương lai…

Xét trên một khía cạnh khác nguồn dữ liệu big data này còn giúp con người có
những trải nghiệm mua sắm, tiêu dùng tốt hơn.

Công nghệ IOS/Android

IOS và Android là 2 hệ điều hành phổ biến được cài đặt trên các thiết bị di động
hiện nay. Mỗi hệ điều hành đều có những ưu điểm riêng nhưng đều có chung mục đích
là tạo lập các ứng dụng, chương trình tiện ích nhằm mang đến người dùng những trải
nghiệm tốt nhất.

Android là hệ điều hành được phát triển bởi Google vào năm 2007. Ngoài
Google còn có các tập đoàn lớn như Samsung, LG, Sony, HTC… chú trọng đầu tư, phát
triển mảng công nghệ này.

IOS cũng chính thức ra mắt vào năm 2007 bởi Apple với sản phẩm đầu tiên là
Iphone. Hiện nay công nghệ này còn được đầu tư phát triển và ứng dụng rộng rãi trên
cả iPad, iPod Touch…

7
Trên đây là top 5 công nghệ đang được ứng dụng và góp phần vào xu hướng tự
động hóa, mang tới sự thay đổi vũ bão trong cách mạng công nghiệp 4.0. Các bạn trẻ
yêu thích CNTT, muốn “vượt bão” cần nhanh chóng nắm bắt những công nghệ này để
không bỏ qua cơ hội thăng hoa sự nghiệp trong kỷ nguyên 4.0.

1.4 Lựa chọn công nghệ phát phát triển


Bạn cần phải xem xét kỹ càng việc áp dụng mô hình ASP.NET MVC hay mô
hình ASP.NET Web Forms khi xây dựng một ứng dụng. Mô hình MVC không phải là
mô hình thay thế cho Web Forms, bạn có thể dùng một trong hai mô hình.

Trước khi quyết định sử dụng MVC hay Web Forms cho một web site cụ thể,
bạn cần phải phân tích lợi ích khi chọn một trong hai hướng.

Lợi ích của ứng dụng web dựa trên mô hình MVC

- Nền tảng ASP.NET MVC mang lại những lợi ích sau:

- Dễ dàng quản lý sự phức tạp của ứng dụng bằng cách chia ứng dụng
thành ba thành phần model, view, controller
- Nó không sử dụng view state hoặc server-based form. Điều này tốt
cho những lập trình viên muốn quản lý hết các khía cạnh của một
ứng dụng.
- Nó sử dụng mẫu Front Controller, mẫu này giúp quản lý các requests
(yêu cầu) chỉ thông qua một Controller. Nhờ đó bạn có thể thiết kế
một hạ tầng quản lý định tuyến. Để có nhiều thông tin hơn, bạn nên
xem phần Front Controller trên web site MSDN
- Hỗ trợ tốt hơn cho mô hình phát triển ứng dụng hướng kiểm thử
(TDD)
- Nó hỗ trợ tốt cho các ứng dụng được xây dựng bởi những đội có
nhiều lập trình viên và thiết kế mà vẫn quản lý được tính năng của
ứng dụng

1.5 Các nền tảng lập trình web

1. Ngôn ngữ lập trình PHP

Đây là ngôn ngữ lập trình phổ biến trong giới lập trình website, có gần 1/3
website trên toàn thế giới sử dụng nền tảng của PHP, có thể kể đến các ông lớn được
xây dựng bằng PHP như Facebook, Yahoo, WordPress,…Hiện nay, lập trình viên PHP
đang được khá nhiều các công ty săn đón, điều đó cho thấy nhu cầu việc làm PHP đang
ngày càng tăng cao.

Ưu điểm:

- Dùng mã nguồn mở (có thể chạy trên Apache hoặc IIS) và ổn định nên
việc cài đặt đơn giản và miễn phí giúp các doanh nghiệp sẽ tiết kiệm
được một khoản chi phí lớn so với việc sử dụng các ngôn ngữ khác.

8
- Phổ biến hơn ASP (có thể thấy dựa vào số website dùng PHP).
- Dễ học khi đã biết HTML, C.
- Dựa vào XAMP (dễ cấu hình).
- Nhiều hệ thống CMS miễn phí dùng.
- Đi cặp với mySQL.

Mặt khác khi sử dụng php để phát triển website và các ứng dụng web thì trang
web của bạn rất linh hoạt, khả năng phản hồi và tương tác rất tốt.

Nhược điểm:

- Mã nguồn không đẹp


- Chỉ chạy trên ứng dụng Web.

2. Ngôn ngữ lập trình Python

Python ra đời từ năm 1989, tính đến nay cũng đã trên 20 năm, nhưng chỉ trong
khoảng trên 5 năm trở lại đây, Python mới dần được nhiều người biết đến và hiện nay
cộng đồng người sử dụng ngôn ngữ này rất đông, nếu so sánh từ bảng xếp hạng các
ngôn ngữ lập trình năm 2017 thì Python đứng thứ 5 trong top 10 ngôn ngữ phổ biến
nhất.

Ưu điểm:

- Có hình thức sáng sủa, cấu trúc rõ ràng, cú pháp ngắn gọn.
- Có trên tất cả các nền tảng hệ điều hành từ UNIX, MS – DOS, Mac OS,
Windows và Linix và các OS khác thuộc họ Unix.
- Tương thích mạnh mẽ với Unix, hardware, third-party software với số
lượng thư viện khổng lồ (400 triệu người sử dụng)
- Với tốc độ xử lý cực nhanh, Python có thể tạo ra những chương trình từ
những script siêu nhỏ tới những phần mềm cực lớn như Biender 3D.

Nhược điểm:

- Không có các thuộc tính như : protected, private hay public


- Không có vòng lặp do…while và switch….case.
- Mặc dù tốc độ xử lý của Python nhanh hơn PHP nhưng không bằng Java
và C++.

3. Ngôn ngữ lập trình Java

Được phát minh vào năm 1991 bởi Oracle, hiện nay Java đang là ngôn ngữ phổ
biến nhất trên thế giới và cũng là một trong những ngôn ngữ lập trình được trả lương
cao, được sử dụng bởi 9 triệu developer và chạy trên 7 tỷ thiết bị trên toàn cầu, là nền
tảng quan trọng để viết ứng dụng cho Android và nhiều phần mềm doanh nghiệp khác.

Java đang đứng ở vị trí số 1 trong cộng đồng lập trình TIOBE, chiếm đến tổng
cộng 20.79% trong danh sách 50 ngôn ngữ lập trình hàng đầu và nó đã lên đến 63%
trên GitHub bằng một số yêu cầu tải về trong mười hai tháng vừa qua. (Nguồn:
9
http://techkids.vn/blog/top-10-ngon-ngu-lap-trinh-nam-2017/) Điểm khác biệt nổi bật
của Java là biên dịch mã nguồn thành bytecode, trong khi ngôn ngữ khác là biên dịch
ngôn ngữ mã nguồn thành mã máy.

Ưu điểm:

- Dùng mã nguồn mở (có thể chạy trên Apache hoặc IIS), mã nguồn rõ ràng,
tách biệt với giao diện HTML.
- Chạy chậm hơn PHP & ASP.NET nhưng có thể cải thiện bằng hardware
- Visual Studio có thể sinh mã, tiết kiệm thời gian viết code.
- Dễ học khi đã biết HTML, C+. Có thể dùng PHP, Ruby… để GUI.
- Dựa vào XAMP + Tomcat plugin (dễ cấu hình).
- Đi cặp Oracle.
- Hoạt động trên Linux, có thể trên IIS – Windows.

Nhược điểm:

- Tốc độ hơi chậm, nhưng chấp nhận được.


- Config nhiều , dễ làm beginet …Giữa PHP và .NET

4. Ngôn ngữ lập trình Javascript

Trong top các ngôn ngữ lập trình web phổ biến cũng cần kể đến JavaScript.
Nghe tên có vẻ giống nhau, tuy nhiên giữa JavaScript và Java chẳng có mối liên hệ gì
với nhau. Có khá nhiều trang web hiện đại ngày nay đều chạy trên JavaScript.

Khi chạy JavaScript trong một trình duyệt bạn không cần phải tải bất cứ phần
mềm nào khác. Bạn chỉ cần một chương trình soạn thảo văn bản và một trình duyệt web
mà thôi. Đây là ngôn ngữ rất dễ tiếp cận cho những bạn mới vào nghề. Hiện nay, việc
làm Javascript cũng đang rất được ưa chuộng ở nhiều doanh nghiệp như hiện nay.

Ưu điểm:

- Hoàn toàn miễn phí và dễ học.


- Thiết kế độc lập với hệ điều hành. Nó có thể chạy trên bất kỳ hệ điều
hành nào có trình duyệt hỗ trợ JavaScript.
- Dễ dàng tương tác, điều khiển và tránh bớt việc xử lý từ phía server.
- Nắm vững kiến thức JavaScript bây giờ rất hữu dụng cho các bạn sau
này để có thể tiếp thu những công nghệ mới mà nó được gói gọn vào
những ngôn ngữ như : Ajax , Atlas ….

Nhược điểm:

- JavaScript không có trình biên dịch riêng mà được diễn dịch và chạy bởi
trình duyệt hỗ trợ nó. Chính vì thế, nếu trình duyệt không hỗ trợ, hoặc không
bật JavaScript, nó sẽ không chạy được.
- Có thể làm ứng dụng web của bạn trở nên nặng nề hơn.
- Bảo mật kém. Không có khả năng giấu mã.

10
5. Ngô n ngữ lập trình C++

C++ có lịch sử trên 30 năm, nó là ngôn ngữ lập trình hướng đối tượng được xây
dựng dựa trên “ông tổ” là ngôn ngữ C, C++ thực sự rất phổ biến với các nhà phát triển
trên toàn cầu. Có nhiều ứng dụng được viết bằng C++, có thể kể đến như: Microsoft
Windows, Google Chrome, Photoshop, PDFReader…. và các tựa game thuộc hàng kinh
điển như AOE, Counter Strike hay Call Of Duty…

Ngôn ngữ C++ cũng đã ảnh hưởng rất lớn đến nhiều ngôn ngữ lập trình web phổ
biến khác như C# và Java.

Ưu điểm:

- Sử dụng ở mọi nơi và kế thừa được các điểm mạnh truyền thống của
ngôn ngữ C như uyển chuyển, tương thích với các thiết bị phần cứng.
- Là ngôn ngữ lập trình hướng đối tượng rất mạnh.
- Dễ mang chuyển đến nền máy khác nếu các nguyên tắc của C++ được
tôn trọng.
- C++ là ngôn ngữ có ít từ khóa, tạo thuận lợi cho việc học và sử dụng.
- Với cấu trúc module cho phép sử dụng nhiều lần các chương trình con
dưới dạng các hàm.
- Có nhiều thư viện sẵn có cho việc thêm các chức năng.

Nhược điểm:

- Khá khó học.


- Chương trình chạy chậm hơn chương trình trong C.
- Tương tác ngược với C nên làm hạn chế khả năng của nó.

1.6 Đưa một website lên mạng Internet


Để đưa trang web của bạn lên mạng, bạn cần phải tìm một cái host và đặt một
cái domain name cho nó. Hai thuật ngữ này có thể hiểu nôm na như sau:

- Host là nơi chứa trang web, là một vùng trên ổ cứng của một cái máy chủ
nào đó. Khi tìm host miễn phí, bạn nên xem host này có dung lượng bao
nhiêu, 100M, 200M, ..., băng thông bao nhiêu (lượng truy cập tối đa cho
phép), có hỗ trợ PHP và MySQL hay không (nếu bạn muốn làm web
động).
- Domain name có thể hiểu là địa chỉ dẫn đến trang web của bạn, như cái
URL ấy. Ví dụ trang web của mình có domain name là
thanhtra.nguyen.free.fr, mình gõ domain name vào thanh address của
trình duyệt thì mình sẽ đến trang web đó.

11
BÀI 2. MÔ HÌNH THIẾT KẾ WEBSITE VỚI MVC
FRAMEWORK
2.1. Giới thiệu mô hình Asp.net MVC
Một câu hỏi thường được đặt ra khi bắt đầu với lập trình web động đó là:

Vấn đề 1: Với web tĩnh ta có thể code trực tiếp mã html và hiển thị được nội
dung trên trình duyệt. Còn với web động, làm sao có thể tạo các nội dung tự động, hay
các nội dung được lấy từ 1 nguồn dữ liệu

Vấn đề 2: Các nội dung ta trên website động được lưu xuống CSDL như thế
nào, và làm thế nào để đọc, thêm, sửa, xóa nội dung ấy

Vấn đề 3: Vấn đề về tương tác nội dung hiển thị trên trình duyệt (xử lý khi
người dùng nhấn vào button, rightl click lên website, hay trang trí định dạng bố cục
website

Với các vấn đề trên ta sẽ đi sau vào mô hình kỹ thuật lập trình MVC để xem
cách thức vận hành của chúng như thế nào.Đồng thời cung cấp các nội dung kiến thức
cần và thường gặp nhất trong phát triển ứng dụng web.

- Mô hình MVC là 1 kỹ thuật lập trình web nhằm phân tách giữa các tầng
ứng dụng. Giúp việc lập trình phát triển, bảo trì ứng dụng được dễ dàng.
- Mô hình MVC trong Asp.net, PHP, JSP cũng có các điểm chung về kỹ
thuật.
- Một lợi thể của Asp.net MVC là được Microsoft tích hợp vào template
của VisualStudio, đồng thời xây dựng sẵn rất nhiều thư viện hỗ trợ lập
trình MVC.
- Mô hình MVC phân chia ứng dụng làm 3 tầng là: Model, View,
Controller

Model: là nơi định nghĩa các lớp của ứng dụng, các lớp định nghĩa cơ sở dữ
liệu.

View: là nơi định nghĩa giao diện để sinh ra các mã html hiển thị trên trình
duyệt.Việc hiển thị nội dung trên View trong MVC dùng các đối tượng Html để hiển
thị.Đây là 1 điểm mới của razor view engine so với webform, làm cho lập trình mvc trở
nên dễ hiểu về view hơn so với webform (trong webform thì dữ liệu được hiển thị bằng
các web Control, tức là khi học webform thì bắt buộc các bạn cần học các thuộc tính
của các loại Control, sau đó aspx Engine sẽ tự động sinh mã html khi chạy ứng dụng )
Còn với MVC thì các bạn không cần học gì hết ngoài việc hiểu biết về Html và 1 ngôn
ngữ.net (C# hoặc vb.net)

Controller: là nơi trao đổi dữ liệu giữa View và Model.Controller sẽ lấy dữ liệu
và trả về View, và Controller cũng lẫy các yêu cầu trên view để xử lý, cũng như tương
tác với CSDL.

12
2.2. MVC và môi trường phát triển Visual Studio
Một điểm mạnh của công nghệ lập trình web Asp.net đó là chúng ta có một IDE
rất tốt của Microsoft để phát triển ứng dụng đó là Visual Studio.

Hiện tại Visual Studio đã có tới phiên bản Visual Studio 2013 Update 3 (và có
bản thử nghiệm Visual Studio 14).

Với Visual Studio 2013 Update 3 chúng ta có một IDE xây dựng mã nguồn rất
mạnh từ việc viết code (hỗ trợ rất nhiều các ngôn ngữ như C#, HTML – HTML5, CSS
– CSS3, Type Script, SASS …).

Ngoài ra Visual Studio 2013 Update 3 cũng thay đổi khá nhiều trong cách biên
dịch và xây dựng ứng dụng.

Đặc biệt là với MVC5 thì Visual Studio 2013 Update 3 cũng tích hợp thêm thư
viện xây dựng giao diện bootstrap hay xây dựng javascript bằng ngôn ngữ hướng đối
tượng Type Script hay CSS với ngôn ngữ SASS.

Một lời khuyên cho các bạn đã lập trình hay mới học lập trình nên cài đặt các
phiên bản mới của Visual Studio để được hỗ trợ viết code, template hay việc biên dịch
tốt hơn.

2.3. Tạo ứng dụng MVC đầu tiên


Thông qua việc mô tả về mô hình MVC tại phần 2 chúng ta đã hiểu 1 phần cấu
trúc của mô hình MVC.

Để hiện thực hóa những điều đó chúng ta đi vào xây dựng 1 ví dụ thực tế để
xem rõ chức năng của các tần Model, View, Controller như thế nào.

Ví dụ đầu tiên chúng ta làm quen cách trao đổi dữ liệu giữa các tầng Model –
View – Controller mà không đi sâu cụ thể vào CSDL.

Đồng thời chúng ta cũng làm quen với cơ chế điều hướng website trong MVC.

Kể từ những bài học sau chúng ta không cần nhắc tới các kỹ năng dùng
VisualStudio để viết code mà chỉ tập chung vào mã nguồn cụ thể.

B1. Khởi động Visual Studio

Có thể chọn ngay từ biểu tượng NewProject từ trang Start Page của VS như
hình sau:

13
B2. Chọn mẫu template là web và cấu hình các thông số về phiên bản.net, nơi
lưu mã nguồn, tên project, tên Solution như hình dưới đây (chú ý 1 solution có thể có
nhiều project làm nhiều chức năng khác nhau để dễ phát triển và bảo trì ứng dụng, các
kỹ thuật này được chúng tôi đề cập trong tài liệu về kỹ thuật lập trình ứng dụng web
MVC):

//Chú ý có thể đặt tên Project không trùng với tên Solution.Trong một solution
có thể có nhiều Project.

Chọn kiểu template MVC để Visual Studio sinh mã tương ứng. Ở đây chúng ta
chọn MVC để Visual Studio sẽ add sẵn các file, folder, thư viện thường dùng trong
ứng dụng MVC)

Với các ví dụ hiện tại dùng cho học tập các bạn nên chọn template là MVC để
VS sinh các mã cần thiết. Khi đã có kiến thức và kinh nghiệm các bạn có thể tạo mẫu
MVC trống rồi tự add các file – thư viện cần thiết theo yêu cầu

Chú ý đặt tên Project có ý nghĩa quan trọng trong việc sinh mã máy.Visual
Studio tự động sinh các lớp có NameSpace dựa theo tên Project.

2.4. Tìm hiểu các thư mục, thư viện Visual Studio tự động sinh
Khi chưa có kinh nghiệm phát triển ứng dụng chúng ta nên để mã máy sinh ra
các thư mục, thư viện thường dùng để phát triển ứng dụng.

Khi có kinh nghiệm chúng ta có thể tùy chỉnh các thư viện phù hợp với mục
đích phát triển ứng dụng.

Việc hiểu các thư viện mã máy sinh ra giúp chúng ta có cái nhìn tổng quan cho
project của chúng ta đang phát triển.

Đầu tiên các bạn nên quan tâm tới 3 thư mục đó là Model, View, Controller.
Đây là nơi sẽ lưu các file.cs,.cshtml tương ứng với các chức năng của mô hình MVC.
Do chúng ta tạo Project mẫu nên Visual Studio tự động sinh sẵn 1 vài Controller, Model
và View tương ứng như là:

14
HomeController, với View tương ứng là Home. Action Index của Home
Controller sẽ được gọi khi chạy ứng dụng.Mã HomeController.

Ngoài ra còn có AccountController, ManagerController dùng cho việc đăng


nhập, đăng ký ứng dụng, hay. Đây đều là các thành phần không thể thiếu của ứng
dụng.Tuy nhiên hiện tại các bạn có thể xóa bỏ chúng để cho ví dụ đơn giản. Chỉ để lại
duy nhất Action Index trong Home Controller

− Ngoài ra chúng ta cũng quan tâm tới các thực mục đó là


− Content: nơi chưa các file css, ảnh
− Script: Chứa các file thư viện javascript như jQuery, MVCajax
− App_Start: đây là thư mục chứa các lớp định nghĩa routed, bundled …
mà ta sẽ học ở các bài sau.

Khi chạy ứng dụng thì View Index trong thư mục: View/Home/Index được gọi.
Việc qui định này được khai báo trong thư File RouteConfig.cs trong thư mục
App_Start.

Nếu bạn nào có chút kiến thức về css, html thì sẽ thắc mắc là chúng ta chưa hề
định dạng layout hay định dạng css cho các thẻ link mà chúng ta đã có 1 giao diện khá
gọn và các link như các button rất đẹp. Câu trả lời ở đây là mẫu MVC5 Visual Studio
đã tích hợp sử dụng thư viện bootstrap.css được đặt tại thư mục Content và được khai
báo sử dụng trong thư mục bundleConfig.cs (App_Start)

Bootstrap là 1 css framework mã nguồn mở khá mạnh để nhanh chóng xây dựng
lên các ứng dụng web giúp các lập trình viên đỡ mất công phái định nghĩa lại các thuôc
tính css nhiều lần. Một điểm yếu của chúng ta với 1 ứng dụng thông thường thì chúng
ta không thể sử dụng hết các chức năng, và gây tình trạng load website chậm. Chúng
tôi sẽ hướng dẫn custom hay học các kỹ thuật code css của bootstrap để các bạn tự xây
dựng css framework bằng ngôn ngữ SASS trong tài liệu về kỹ thuật lập trình MVC.

Phần kế tiếp chúng ta đi xây dựng đầy đủ 3 thành phần Model, View, Controller
và tương tác đọc, hiển thị và lưu trữ dữ liệu để các bạn hiểu rõ bản chất mô hình MVC

2.5. Route và cấu hình route trong MVC


Route (bộ định tuyến) trong MVC là các khai báo để ứng dụng MVC có thể biết
được Action và Controller nào sẽ được gọi để xử lý yêu cầu từ phía người dùng.

Khác với trong webform, việc gọi các file aspx đường dẫn mang tính vật lý, thì
các việc dùng route mang tính code và chúng ta có thể tùy biến các route để được các
URL trông gọn gàng và mạch lạc.

// Trong Ví dụ phần 1 trước, khi chạy ứng dụng thì HomeController được gọi.Và
ta muốn biết xem việc định nghĩa Controller nào được gọi, và cơ chế gọi như thể nào ?

15
// Trong MVC 4, MVC 5 thì việc định nghĩa Routed được khai báo trong
lớp RouteConfig.cs

(file này trong thư mục App_Start )

// Trong MVC 2, MVC 3 thì được khai báo trong file Global.asax

// Mã khai báo Routed như sau:

public class RouteConfig

public static voidRegisterRoutes(RouteCollection routes)

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(

name: "Dentitype frameworkault",

url: "{controller}/{action}/{id}",

dentitype frameworkaults: new { controller = "Home", action


= "Index", id = UrlParameter.Optional }

);

ta có thể định nghĩa nhiều Route, ở đây VS tạo sẵn 1 route có tên là Dentitype
frameworkault.

Ở đây ta thấy Home Controller, Action Index là giá trị mặc địn khi ứng dụng
chạy.

Việc gọi các Action trong Controller bất kỳ tuân theo cấu trúc:

/TenController/Action/ThamSo

Với những Action không có tham số thì chỉ cần gọi:

/TenController/Action/

Với Action có tên là Index thì chỉ cần gọi: /TenController

16
Ví dụ:

Nếu muốn khi khởi chạy ứng dụng thì Action Index của Sample1Controller
được gọi thì khai báo như sau:

routes.MapRoute(

name: "Dentitype frameworkault",

url: "{controller}/{action}/{id}",

dentitype frameworkaults: new { controller = "Sample1”, action


= “Index”, id = UrlParameter.Optional }

);

// khởi tạo mới 1 Route như sau:

routes.MapRoute(

"LogOn",

"Admin/{action}/{id}",

new { controller = "Account", action = "Index",id="" }

);

// khi người dùng nhập: /admin

thì Action Index của AccountController được gọi.

Khi 1 yêu cầu từ phía client thì router sẽ tiến hành map từ trên xuống dưới, khi
nào tìm được route có đủ các yêu cầu về tham số và tên thì dừng lại.

Do đó khi tự tạo các route cần chú ý các vấn đề tham số và tên để yêu cầu tìm
được đúng Controller và Action cần để xử lý. Có những Action từ các Controller khác
nhau nhưng có cùng tham số đôi khi lại bị xử lý lẫn nhau nếu route khai báo không
chính xác.

2.6. Route và SEO


Việc dùng router trong MVC giúp chúng ta xây dựng các URL rất gọn và dễ
dàng cho các công cụ tìm kiếm.

Trong 1 ứng dụng chúng ta thường có nhiều Controller khác nhau. Tuy nhiên
chúng ta nên xây dựng lại các router để khi xem 1 nội dung nào đó url luôn có cấu trúc
như sau:

http://domain/noi-dung-bai-viet/12345
17
Trong đó:

domain: là tên miền website

noi-dung-bai-viet: chứa từ khóa cần seo

123456: là mã của bài viết và có thể thêm mã loại vào đây để phân biệt giữa các
Controller

Với các kiến thức đã có từ Route phần trên các bạn hoàn toàn có thể xây dựng
được các URL thân thiện với các công cụ tìm kiếm.

Các bạn có thể xem URL của các website như:

http://laptrinhviet.net http://dantri.com http://vnexpress.net … để xem cấu trúc


các URL của họ để học tập các xây dựng URL chuẩn SEO.

Còn thực sự để làm được điều đó các bạn có thể đọc tài liệu xây dựng ứng dụng
MVC chuẩn SEO của chúng tôi để được hướng dẫn chi tiết từng bước xây dựng các
URL chuẩn SEO và các kỹ năng xây dựng web hỗ trợ SEO khác.

BÀI 3. CÁC THÀNH PHẦN TRONG MVC


3.1. Model
Các đối tượng Models là một phần của ứng dụng, các đối tượng này thiết lập
logic của phần dữ liệu của ứng dụng. Thông thường, các đối tượng model lấy và lưu
trạng thái của model trong CSDL. Ví dụ như, một đối tượng Product (sản phẩm) sẽ lấy
dữ liệu từ CSDL, thao tác trên dữ liệu và sẽ cập nhật dữ liệu trở lại vào bảng Products
ở SQL Server.

Trong các ứng dụng nhỏ, model thường là chỉ là một khái niệm nhằm phân biệt
hơn là được cài đặt thực thụ, ví dụ, nếu ứng dụng chỉ đọc dữ liệu từ CSDL và gởi chúng
đến view, ứng dụng khong cần phải có tầng model và các lớp lien quan. Trong trường
hợp này, dữ liệu được lấy như là một đối tượng model (hơn là tầng model).

Mã lớp Person như sau

public class Person

public int ID { get; set; }

public string Name { get; set; }

18
}

// Đây là Class dùng để lưu trữ thông tin cũng như xử lý dữ liệu. Hiện tại ta chưa
quan tâm tới việc lưu trữ dữ liệu.Nên ta sẽ tạo tự động 1 bộ dữ liệu lưu trên bộ nhớ.Sau
này lớp Person sẽ ánh xạ tạo 1 bảng dưới CSDL.

// Để tạo ra danh sách Person trên bộ nhớ tạo sẵn 1 phương thức tĩnh như sau
(khi lập trình tạo CSDL thực sự thì không cần tạo phương thức này )

public static IEnumerable<Person> GetData(int Count) {

varPersons = new List<Person>();

for (int i = 1; i <= Count; i++)

Persons.Add(new Person { ID=i, Name="Person"+i.ToString()});

returnPersons;

// Phương thức GetData trả về 1 List<Person>.Và là 1 phương thức tính.Ở đây


sử dụng 1 vài tính năng của C# 3.0.Các bạn có thể xem lại cách dùng lớp List<T>, tạo
mới đối tượng trong C# 3.0 và phương thức tính (static )

// Lớp Person hoàn chỉnh là:

public class Person

public int ID { get; set; }

public string Name { get; set; }

public static IEnumerable<Person> GetData(int Count) {

varPersons = new List<Person>();

for (int i = 1; i <= Count; i++)

Persons.Add(new Person { ID=i, Name="Person"+i.ToString()});

19
}

returnPersons;

Với C# 3.0 chúng ta dùng từ khóa yield để làm gọn phương thức GetData như
sau:

public static IEnumerable<Person> GetData(int Count)

for (int i = 1; i <= Count; i++)

yield return new Person { ID = i, Name = "Person "+i.ToString() };

3.2. Controller
Controller là các thành phần dùng để quản lý tương tác người dùng, làm việc
với model và chọn view để hiển thị giao diện người dùng. Trong một ứng dụng MVC,
view chỉ được dùng để hiển thị thông tin, controller chịu trách nhiệm quản lý và đáp trả
nội dung người dùng nhập và tương tác với người dùng. Ví dụ, controller sẽ quản lý
các dữ liệu người dùng gởi lên (query-string values) và gởi các giá trị đó đến model,
model sẽ lấy dữ liệu từ CSDL nhờ vào các giá trị này.

Đặt tên cho Controller ở đây ta đặt tên Controller là Sample1Controller:

// Mã Sample1Controller như sau:

public class Sample1Controller: Controller

public ActionResultIndex()

20
{

returnView(Person.GetData(10));

Chú ý khai báo name space lớp Person:

usingSampleMVC.Models;

Phân tích:

Ở đây Sample1Controller kế thừa lại lớp Controller (1 lớp Microsoft cung cấp
sẵn trong thư viện Asp.net MVC ).

// Ta chú ý tới Action Index là 1 ActionResult, Action này trả về 1 View (kiểu
html )

// Trong Controller có thể có các phương thức trả về các kiểu dữ liệu thông
thường như là string, int, class …

// Action Index trả về 1 View (các thẻ html).View này có tên là Index và phải
đặt trong thư mục: View/Sample1/Index.cshtml.View này dùng hiển thị dữ liệu danh
sách Person.Phương thức Person.GetData(10) trả về danh sách 10 Person, và sẽ được
hiển thị lên View.

3.3. View
Views là các thành phần dùng để hiển thị giao diện người dùng (UI). Thông
thường, view được tạo dựa vào thông tin dữ liệu model. Ví dụ như, view dùng để cập
nhật bảng Products sẽ hiển thị các hộp văn bản, drop-down list, và các check box dựa
trên trạng thái hiện tại của một đối tượng Product.

Ta tạo View Index như sau:

// Chuột phải lên Action Index chọn add View, hoặc tạo thư mục Sample1 trong
thư mục View:

Hoặc Chuột phải vào thư mục View có tên trùng với tên Controller tương ứng

Ta chú ý tới các thông số:

View name: tên view, tương ứng với tên Action ở đây là Action Index thì ta cần
khai báo là Action Index. Tức là Action Index sẽ trả về View Index, giả sử ta có thể qui
định Action Index trả về View bất kỳ như sau:

21
public ActionResultIndex()

returnView("SampleView",Person.GetData(10));

Khi này ta phải đặt tên View là SampleView

Template: là kiểu dữ liệu sẽ được View nhận về, ở đây ta khai báo kiểu là list
thì model trong View sẽ nhận về kiểu IEnumable<T>

Model class: ta chọn là Person, cụ thể ở đây View sẽ nhận về kiểu


IEnumable<Person>

Chú ý:

Với Visual Studio 2012 và các phiên bản trước ta phải build Project (Chuột phải
vào Project chọn Build, nếu là các lần sau chọn Rebuild) thì mới hiện lớp Person để ta
lựa chọn.

// Layout là là 1 file để các View khác kể thừa (tương tự như masterpage trong
Asp web form ). Hiện tại tam thời ta không quan tâm tới file _Layout.cshtml code như
thể nào.Việc xây dựng layout dẽ được học trong các bài học tiếp.

Ở đây ta tạo các thông số để VS tự động sinh mã Razor để hiển thị (Việc từ
Razor sinh ra mã HTML là nhiệm vụ của Razor View Engine ).

Khi đã có kiến thức, và kinh nghiệm các bạn có thể tùy biến tự tạo View, mà
không cần để VS sinh sẵn mã máy.Tuy nhiên mã máy hoàn toàn đáp ứng được các yêu
cầu cơ bản.

// Mã View do VS sinh ra sẽ như sau:

@model IEnumerable<SampleMVC.Models.Person>

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Index</h2>

<p>

22
@Html.ActionLink("Create New", "Create")

</p>

<table class="table">

<tr>

<th>

@Html.DisplayNamentitype frameworkor(model => model.Name)

</th>

<th></th>

</tr>

@foreach (var item in Model) {

<tr>

<td>

@Html.DisplayFor(modelItem => item.Name)

</td>

<td>

@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |

@Html.ActionLink("Details", "Details", new { id=item.ID }) |

@Html.ActionLink("Delete", "Delete", new { id=item.ID })

</td>

</tr>

</table>

Ta chú ý tới khai báo kiểu dữ liệu View nhận về trong biến Model là:

@model IEnumerable<SampleMVC.Models.Person>

Và trong Razor ta dùng vòng lặp duyệt qua Model để hiển thị dữ liệu lên thẻ
table html

23
Chú ý: Những ví dụ sau khi nói đến chạy View nào các bạn chỉ cần chuột phải
lên view đó và làm tương tự.

URL của Action này như sau:

http://localhost:1761/Sample1/Index

Khi chạy ứng dụng bạn cũng chỉ cần tham chiếu tới đường dẫn: sample/index
thì sẽ gọi tới Action này.

Các tính năng trên thẻ link Create, Delete, Edit, Details ta chưa xây dựng

3.4. Mô hình MVC không đầy đủ


Không phải mô hình MVC cần có đầy đủ các đối tượng Model, View hay
Controller.

Có những Action không trả về dư liệu từ CSDL (tức là ta không cần dùng Model
) Hay có trường hợp Action không trả về View (kiểu html ) mà chỉ trả về 1 kiểu dữ liệu
thông thường như int, string hay kiểu json hoặc trả về 1 file … khi này không cần tới
View.Việc gọi tới các Action này thường thông qua các lời gọi ajax từ các View khác

− Xét ví dụ không dùng đến Model


− Thêm Action ViDu1 trong Sample1Controller như sau

public ActionResult ViDu1()

returnView();

ViDu1 View:

<h1>Hello world</h1>

<h2>Đây là View ViDu1 của Action ViDu1</h2>

Ta thấy View chỉ dùng các thẻ html để hiển thị thông tin.

BÀI 4. TH 1. ỨNG DỤNG MVC CĂN BẢN


Bài 1. Tạo ứng dụng MVC và viết câu chào: Hello MVC trên trình duyệt
web

24
Mục đích

- Giúp người người làm quen với cách thức tạo ứng dụng MVC
- Thực hiện việc xuất dữ liệu ra màn hình

Hướng dẫn

- Thực hiện các bài tập tạo Controller cho phép hiển thị câu chào “Hello
world!”
- Thực hiện tạo Form trên trang views và cho phép nhập vào họ tên sau đó in
ra câu chào.
- Thực hiện bài truyền biến từ Controller và View thông qua Viewbag

Bài 2: Tạo ứng dụng giải phương trình bậc 1

Mục đích

Giúp sinh viên làm quen với phương pháp truyền giá trị giữa Controller và
View.

Thực hiện được các bài toán cơ bản trên MVC Hướng dẫn

Hướng dẫn

- B1. Tạo Controller ptb1


- B2. Thiết kế form giải phương trình gồm các biến a, b
- B3. Thực hiên nhận giá trị từ các biến và giải phương trình kết quả in ra màn
hình

Bài tập tự làm

Bài 3. Thực hiện viết chương trình giải phương trình bậc 2

Mục đích

Giúp sinh viên làm quen với phương pháp truyền giá trị giữa Controller và
View.

Thực hiện được các bài toán cơ bản trên MVC

Hướng dẫn

B1. Tạo Controller ptb2

B2. Thiết kế form giải phương trình gồm các biến a, b, c

B3. Thực hiên nhận giá trị từ các biến và giải phương trình kết quả in ra màn
hình
25
Bài 4. Thực hiện viết chương trình giải hệ phương trình bậc nhất 2 ẩn số

Mục đích

Giúp sinh viên làm quen với phương pháp truyền giá trị giữa Controller và
View.

Thực hiện được các bài toán cơ bản trên MVC

Hướng dẫn

B1. Tạo Controller hpt

B2. Thiết kế form giải phương trình gồm các biến a, b, c, a1, b1, c1

B3. Thực hiên nhận giá trị từ các biến và giải phương trình kết quả in ra màn
hình

Bài 5. Thực hiện tạo một lớp sinh viên gồm các thong tin sau:

- Mã sinh viên
- Họ và tên
- Ngày sinh
- Quê quán
- Điểm toán
- Điểm lý
- Điểm hóa
- Tổng điểm

Yêu cầu:

Thực hiện tạo một List các sinh viên vừa được định nghĩa và thực hiện

- Sắp xếp sinh viên theo tổng điểm từ cao đến thấp
- Tìm kiếm sinh viên theo họ tên, mã sinh viên, ngày sinh, quê quán

Mục đích

- Giúp học viên làm quen với việc sử dụng vòng lặp và sắp xếp dữ liệu trên
List
- Cho phép hiển thị dữ liệu ra table

Bài 6. Thực hiện tạo một lớp thu tiền điện gồm các thong tin sau:

- Mã hộ gia đình
- Họ và tên
- Số công tơ tháng trước

26
- Số công tơ hiện tại
- Tổng điện tiêu thụ
- Thành tiền

Yêu cầu:

Tạo một List các hộ gia đình và thực hiện tính tiền điện hang tháng biết

Nếu số điện<100:Thành tiền=số điện * 1200

Nếu số điện >100 thì từ 100-180 số điện vượt quá 100 sẽ được tính bằng 1700/sô

Nếu số điện >180 số thì từ số 180 trở đi tính 2500/số

27
BÀI 5. SỬ DỤNG ENTITYFRAMEWORK TRONG
MVC
5.1. Giới thiệu về EntityFramework
Ta đã làm quen với mô hình MVCxử lý dữ liệu dưới dạng dữ liệu trên bộ
nhớ.Tiếp theo ta sẽ làm quen với việc thao tác với CSDL thực sự.

Sql Comact

Ở đây ta sử dụng Sql Compact 4. 0.Việc sử dụng Sql Compact hoàn toàn tương
tự việc sử dụng Sql Server, Sql local.

Sql Compact có thể được ta tích hợp vào như là 1 thành phần của Project, nên
dễ dàng trong việc triển khai hay thuê hosting (các gói cước giá thấp nhất thường không
hỗ trợ database thì hoàn toàn có thể dùng sql Compact như là một sự thay thể cho CSDL
Sql Server )

Sql Compact hỗ trợ 4 GB dữ liệu như Sql Server Express

Chú ý khi cài VS 2012 thì mặc định Sql compact được cài theo.Khi public các
ứng dụng web dùng Sql Compact làm CSDL.Máy chủ làm hosting cần cài đặt phiên
bản Sql Compact tương ứng với bản làm CSDL.Hoặc ta có thể tích hợp Sql Compact
vào như là 1 phần của website, khi này máy chủ không cần cài đặt Sql Compact

Entity Framework

Khi sử dụng entitype framework chúng ta có 3 lựa chọn đó là:

Database First (thiết kế database trước ), sau đó dùng VS tạo lớp entity.Kỹ thuật
này giống với kỹ thuật tạo lớp Entity dùng Linq to Sql.

Model fist: Dùng VS tạo lớp Entity, sau đó từ Entity sinh ra database

Code first: Tạo các lớp ứng dụng, và lớp Entity như các đối tượng C# (vb.net )
thông thường.Khi ứng dụng chạy sẽ tự động tạo ra 1 CSDL tương ứng với các lớp.

Thông thường ENTITYPE FRAMEWORK code first được sử dụng nhiều, do


có thể thấy rõ được bản chất của lớp Entity đồng thời dễ tùy biến các thuộc tính theo
tính chất đối tượng.

Trong một vài trường hợp có thể sử dụng ENTITYPE FRAMEWORK database
first, model first

Dưới đây chúng ta sẽ sử dụng mô hình code first để làm demo cho các bài học.

28
5.2. Tạo lớp Entity định nghĩa kết nối đến Cơ sở dữ liệu
Với MVC 5 tạo trên VS 2013 thì VS tự động thêm dll của EntityFramwork của
EntityFramwork 6.0.

Có thể dùng nuget lấy về bản ENTITYPE FRAMEWORK mới nhất theo hướng
dẫn sau:

// Cài đặt bằng nuget:

Tool/Library Package Manager / Package Manage Console

Lệnh cập nhật gói ENTITYPE FRAMEWORK:

Install-Package EntityFramework

Sau khi chạy lệnh trên Visual Studio sẽ tự động download gói ENTITYPE
FRAMEWORK trong thư mục packages.Và tự động add các thư viện dll vào dự án.

Chú ý: Với phiên bản Visual Studio 2013 thì sql compact không tích hợp các
thư viện tương tác với Entity Framework do đó nếu dùng CSDL sql Compact chúng ta
nhập thêm lệnh sau để cập nhật thư viện tương tác xử lý sql compact với Entity
Framework. Mã lệnh cập nhật như sau:

PM> Install-Package EntityFramework.SqlServerCompact

Để tích hợp sql Compact vào như 1 thành phần của Project các bạn có thể gọi
gói cập nhật sau:

PM> Install-Package SqlServerCompact

Khi này thì Sql Compact như 1 thành phần của Projetc, khi upload lên hosting
thì không cần Hosting có hỗ trợ Sql Compact. Với máy tính các bạn thực hành dùng
Visual Studio 2013 hay Visual Studio 2012 thì hiện tại không dùng đến lệnh này.

Các bạn có thể tham khảo 1 các thư viện mà nuget cập nhật vào project cho
chúng ta để sau này các bạn có thể tự add vào project những thư viện cần thiết

tại thư mục Model tạo class AppEntity có code như sau:

public class AppEntity:DbContext

public DbSet<Student> Students { get; set; }

protected override voidOnModelCreating(DbModelBuilder modelBuilder


)
29
{

modelBuilder.Conventions.Remove<PluralizingTableNameConventio
n>();

Lớp Student khi này ta code lại như sau:

public class Student

public int ID { get; set; }

public string Name { get; set; }

Chú ý thuộc tính Student ID phải có hậu tố là ID để ENTITYPE


FRAMEWORK tự động hiểu đây là trường khóa.Nếu đặt tên bất kỳ thì cần khai báo
Attribute key cho trường có như sau:

public class Student

[Key]

public int ID { get; set; }

public string Name { get; set; }

Ở đây ta chỉ có bảng Student.Với CSDL có nhiều bảng ta làm tương tự, với các
bảng dữ liệu chứa quan hệ sẽ được hướng dẫn ở các phần kế tiếp

Chú ý add các nameSpace sau:

using System.Data.Entity;

usingSystem.Data.Entity.ModelConfiguration.Conventions;

5.3. Tạo chuỗi kết nối và khai báo dữ liệu mặc định
Chuỗi kết nối:

30
Tại file web.config, thẻ connectionStrings

xóa bỏ chuỗi kết nối mặc định có tên là Dentitype


frameworkaultConnectionString

<connectionStrings>

<add name="AppEntity" connectionString="Data


Source=|DataDirectory|SampleMvc.sdf"

providerName="System.Data.SqlServerCe.4.0"/>

</connectionStrings>

Chú ý tên chuỗi kết nối phải đặt trùng với tên của lớp Entity, ở đây là AppEntity.

Dữ liệu Sql Compact là 1 file.sdf sẽ được lưu tại thư mục App_Data của Project.

Khi dùng CSDL khác (Sql Server, Sql local thì chỉ cần thay đổi chuỗi kết nối ở
đây ) Tạo dữ liệu mặc định:

Có nhiều trường hợp ta cần tạo dữ liệu mặc định (có thể không cần trong trường
hợp này ) ví dụ như việc tạo các User hệ thống, các dữ liệu cấu hình website …

Tạo mới File Dentitype frameworkaultData trong thư mục Model và code như
sau:

public class Dentitype


frameworkaultData: DropCreateDatabaseIfModelChanges<AppEntity>

protected override voidSeed(AppEntity context)

new List<Student> {

new Student { ID=1, Name="Student 1"},

new Student { ID=2, Name="Student 2"},

new Student { ID=3, Name="Student 3"}

}.ForEach(m => context.Students.Add(m));

31
Đăng ký dữ liệu mặc định:

Trong file Global.asax khai báo thêm dòng code sau vào cuối phương thức
Application_Start

Database.SetInitializer(new Dentitype frameworkaultData());

// Codel toàn bộ file Global.asax

public class MvcApplication: System.Web.HttpApplication

protected voidApplication_Start()

AreaRegistration.RegisterAllAreas();

WebApiConfig.Register(GlobalConfiguration.Configuration);

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

RouteConfig.RegisterRoutes(RouteTable.Routes);

BundleConfig.RegisterBundles(BundleTable.Bundles);

AuthConfig.RegisterAuth();

System.Data.Entity.Database.SetInitializer(newSampleMVC.Models.D
entitype frameworkaultData()); }

5.4. Truyền dữ liệu Controller – View


việc lấy dữ liệu và hiển thị dữ liệu tương tự như việc lấy hiển thị dữ liệu khi làm
việc với dữ liệu trên bộ nhớ.

Controller: Tạo Sample2Controller

AppEntity db = new AppEntity();

public ActionResultIndex()

32
returnView(db.Students);

View: (cách tạo View tương tự như View Index của Sample1Controller )

View Index:

@model IEnumerable<SampleMVC.Models.Student>

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Index</h2>

<p>

@Html.ActionLink("Create New", "Create")

</p>

<table class="table">

<tr>

<th>

@Html.DisplayNamentitype frameworkor(model => model.Name)

</th>

<th></th>

</tr>

@foreach (var item in Model) {

<tr>

<td>

@Html.DisplayFor(modelItem => item.Name)

33
</td>

<td>

@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |

@Html.ActionLink("Details", "Details", new { id=item.ID }) |

@Html.ActionLink("Delete", "Delete", new { id=item.ID })

</td>

</tr>

Build lại Projetc (bất kỳ việc thay đổi mã.cs (trong model hoặc Controller) đều
phải build lại projetc)

Ở đây kết quả tương tự như Sample1Controller (Index Action ).Tuy nhiên ở đây
ta đã tạo và sử dụng 1 cơ sở dữ liệu thực sự.Các bạn mở thư mục App_Data ta có 1
file SampleMvc.sdf. Đây chính là file CSDL Sql Compact (Có thể phải Rentitype
frameworkresh lại Solution trong Visual Studio để thấy rõ CSDL này ).Việc đặt tên
cũng như đường dẫn file CSDL được qui định tại chuỗi kết nối trong file web.config

34
BÀI 6. LẬP TRÌNH MVC VỚI ENTITY
FRAMEWORK
6.1. Thao tác thêm – sửa – xóa dữ liệu dùng Entity Framework
Một website động tức là nội dung của chúng có thể được cập nhật, thay đổi bất
kỳ lúc nào.

Do đó việc thay đổi nội dung (thêm mới, sửa, xóa) là những thao tác khá cơ bản
mà chúng ta cần phải làm được khi học phát triển ứng dụng web

Ngoài ra với 1 website thực tế thì có thêm rất nhiều tương tác giữa người dùng
và ứng dụng.

Các tương tác với CSDL thường là: Thêm, sửa, xóa, truy vấn, lọc, tìm kiếm.

Trong lập trình web MVC, với EntityFramework các tương tác với CSDL
thường dùng các truy vấn Linq thay cho Ado.net.

IDE VS hỗ trợ rất mạnh việc sinh ra mã máy, tuy nhiên chúng ta nên code bằng
tay để hiểu bản chất.Sau này tùy vào độ phức tạp của ứng dụng mà ta sử dụng việc mã
máy hay mã tay 1 cách hợp lý.

6.2. Hiển thị dữ liệu


Tương tự như Sample1Controller chúng ta sẽ hiển thị danh sách student để quản
lý và xử lý các thao tác Create, Edit, Delete, Details

Controller

AppEntity db = new AppEntity();

public ActionResultIndex()

returnView(db.Students);

View

@model IEnumerable<SampleMVC.Models.Student>

@{

ViewBag.Title = "Index";

35
Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Index</h2>

<p>

@Html.ActionLink("Create New", "Create")

</p>

<table class="table">

<tr>

<th>

@Html.DisplayNamentitype frameworkor(model => model.Name)

</th>

<th></th>

</tr>

@foreach (var item in Model) {

<tr>

<td>

@Html.DisplayFor(modelItem => item.Name)

</td>

<td>

@Html.ActionLink("Edit", "Edit", new { id=item.ID }) |

@Html.ActionLink("Details", "Details", new { id=item.ID }) |

@Html.ActionLink("Delete", "Delete", new { id=item.ID })

</td>

</tr>

36
</table>

Ta quan tâm tới các ActionLink:

@Html.ActionLink("Create New", "Create"): Action Link này sẽ sinh ra 1 thẻ


a gọi tới Action Create, cụ thể là: sample3/create

@Html.ActionLink("Edit", "Edit", new { id=item.ID }): ActionLink sinh ra thẻ


a gọi tới Action Edit, với tham số truyền vào là id Student cần sửa

Tương tự ta có các Action Delete, Details

6.3. Thêm mới dữ liệu


Chúng ta sẽ thực hiện thao tác thêm mới 1 Student và lưu xuống CSDL một các
đơn giản nhất.

Khi đã có những kiến thức mạnh hơn và trong 1 vài trường hợp có thể chúng ta
sẽ dùng thêm các kỹ thuật lập trình Ajax, jQuery, Web API để tạo nên các tương tác
thuận tiện hơn cho người dùng

Create Action

[HttpGet]

public ActionResultCreate()

returnView();

[HttpPost]

public ActionResultCreate([Bind(Exclude = "ID")]Studentmodel)

if(ModelState.IsValid)

db.Students.Add(model);

db.SaveChanges();

returnRedirectToAction("Index");

37
}

returnView(model);

Action Index để hiển thị danh sách Student

// Có 2 Action Create để thêm mới Student

1 Action được gọi để trả về 1 View dùng để nhập các giá trị của Student là: ID,
Name. Được đặt sau Attribute: HttpGet

1 Action được gọi khi người dùng nhấn nút thêm mới trên View để post dữ
liệu.Phương thức này đặt sau Attribute: HttpPost.Action này nhận vào tham số là 1 đối
tượng Student, sau đó dùng câu truy vấn Linq để thêm mới dữ liệu.

Các bạn thấy việc truy vấn thêm mới dữ liệu dùng Linq và Entity Framework
rất là đơn giản hơn nhiều so với Ado.net.

Lệnh db.Students.Add(model); để thêm dữ liệu lên đối tượng Context

Lệnh db.SaveChanges(); thực sự lưu những thay đổi xuống CSDL.

Các bạn có thể tìm hiểu các kiến thức này trong tài liệu lập trình CSDL với Linq
Entity Framework của chúng tôi.

Ta chú ý thêm 1 thành phần đó là: [Bind(Exclude="ID")]

Đây là khai báo để chỉ định trường ID (là trường khóa tự động tăng không cần
nhập ).Khi post dữ liệu từ View lên Controller, thuộc tính ID chưa được khai báo, nếu
không chỉ định thuộc tính không cần khai báo thì sẽ phát sinh lỗi.

Có thể thay đổi khai báo loại bỏ kiểm tra khai báo thuộc tính ID bằng mã sau:

ModelState.Remove("ID");

Khi này tính năng Validation của MVC sẽ không kiểm tra việc nhập thiếu
trường ID.

Khai báo ModelState.IsValid dùng để kiểm tra trường nhập liệu xem người
dùng có nhập đúng kiểu giá trị hay có nhập giá trị không. Ví dụ trường nhập liệu yêu
cầu nhập vào số và người dùng nhập chữ thì MVC tự động báo lỗi và dừng ứng dụng.

Giả sử ở đây ta khai báo trường Name của lớp Student là không được để
trống(bắt buộc phải nhập) như sau:

public class Student


38
{

[Key]

public int ID { get; set; }

[Required(ErrorMessage="Khong de trong")]

public string Name { get; set; }

Khi này tính năng ModelState.IsValid sẽ kiểm tra xem người dùng có nhập liệu
hay không

Sau khi thêm mới thành công, mvc sẽ tự động điều hướng tới trang Index bằng
mã:

returnRedirectToAction("Index");

Chúng ta có thể khai báo điều hướng tới trang bất kỳ, kể cả các trang chứa tham
số

View: Create

// tạo View Create tương tự view Index tuy nhiên ta lựa chọn template là Create

Mã VS tự động tạo ra như sau:

@model SampleMVC.Models.Student

@{

ViewBag.Title = "Create";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Create</h2>

@using (Html.BeginForm())

@Html.AntiForgeryToken()

<div class="form-horizontal">
39
<h4>Student</h4>

<hr />

@Html.ValidationSummary(true, "", new { @class = "text-danger" })

<div class="form-group">

@Html.LabelFor(model => model.Name, htmlAttributes: new {


@class = "control-label col-md-2" })

<div class="col-md-10">

@Html.EditorFor(model => model.Name, new { htmlAttributes


= new { @class = "form-control" } })

@Html.ValidationMessagentitype frameworkor(model =>


model.Name, "", new { @class = "text-danger" })

</div>

</div>

<div class="form-group">

<div class="col-md-offset-2 col-md-10">

<input type="submit" value="Create" class="btn btn-dentitype


frameworkault" />

</div>

</div>

</div>

<div>

@Html.ActionLink("Back to List", "Index")

</div>

Ở đây Visual Studio dùng thư viện Bootstrap để định dạng trang thêm mới. Mã
rất rối, chúng tôi chỉnh sửa lại cho đơn giản để các bạn có thể dễ dàng hiểu hơn như
sau:

@model SampleMVC.Models.Student

40
@{

ViewBag.Title = "Create";

Layout = "~/Views/Shared/_Layout.cshtml";

@using (Html.BeginForm())

@Html.ValidationSummary(true)

@Html.LabelFor(m => m.Name)

<div>

@Html.EditorFor(m => m.Name)

@Html.ValidationMessagentitype frameworkor(m => m.Name)

</div>

<p>

<input type="submit" value="Lưu lại" />

</p>

Các bạn đã thấy mã nguồn khá đơn giản hơn so với mã máy tự sinh.

@using (Html.BeginForm()) {}: Là 1 Html Helper sinh ra thẻ form html

@Html.ValidationSummary(true): Khai báo kiểm tra nhập liệu tại Client không,
chúng tôi sẽ nói rõ trong phần tới

@Html.LabelFor(m => m.Name): Htlm Helper sinh ra lable tiêu đề tên trường
nhập liệu, ở đây sẽ hiển thị tên trường là Name

@Html.EditorFor(m => m.Name): Htlm Helper sinh ra 1 thẻ textBox để nhập


liệu

@Html.ValidationMessagentitype frameworkor(m => m.Name): Helper hiển


thị lỗi khi nhập liệu không chính xác.

Trường hợp có nhiều trường dữ liệu chúng ta làm tương tự

41
Nhập tên Stuent và nhấn vào nút Lưu lại thì 1 Student sẽ được thêm mới và lưu
xuống CSDL, và mvc sẽ tự động điều hướng về trang Index

Nếu các bạn có chút kiến thức về html thì có thể xem mã html sinh ra để thêm
mới Student như sau:

<form action="/Sample3/Create" method="post">

<label for="Name">Name</label> <div>

<input class="text-box single-line" data-val="true" data-val-


required="Khong de trong" id="Name" name="Name" type="text" value="" />

<span class="field-validation-valid" data-valmsg-for="Name" data-


valmsg-replace="true"></span>

</div>

<p>

<input type="submit" value="Lưu lại" />

</p>

</form>

1 Form nhập liệu được tạo ra với thẻ input nhập liệu và các thuộc tính kiểm tra
nhập liệu. Việc kiểm tra mã code html sinh ra từ Razor rất quan trong với các bạn lập
trình để có thể kiểm soát mã html sinh ra để tùy biến xử lý.

Để hiển thị tiếng Việt mô tả thuộc tính name của Student ta có thể thay đổi trong
lớp Student như sau:

public class Student

[Key]

public int ID { get; set; }

[Required(ErrorMessage="(*)Không được để
trống"),Display(Name="Tên Học Sinh")] public string Name { get; set; }

Ở đây ta đã bật tính năng kiểm tra nhập liệu, trường Name của Student không
được để trống với lệnh: @Html.ValidationSummary(true)

42
Và mã @Html.ValidationMessagentitype frameworkor(m => m.Name) dùng
để hiển thị thông báo lỗi.

Ta cần khai báo thêm thư viện javascript kiểm tra nhập liệu sau:

<script src="~/Scripts/jquery.validate.js"></script>

Thư viện này cũng được tự động tích hợp khi ta tạo Project, lưu trong thư mục
Script.View Create sẽ như sau:

@model SampleMVC.Models.Student

@{

ViewBag.Title = "Create";

Layout = "~/Views/Shared/_Layout.cshtml";

@using (Html.BeginForm())

@Html.ValidationSummary(true)

@Html.LabelFor(m => m.Name)

<div>

@Html.EditorFor(m => m.Name)

@Html.ValidationMessagentitype frameworkor(m => m.Name)

</div>

<p>

<input type="submit" value="Lưu lại" />

</p>

@section Scripts {

@Scripts.Render("~/bundles/jqueryval")

43
Ở đây dùng tính năng bundled của MVC4,MVC5, có thể khai báo trực tiếp như
sau:

@section Scripts {

<script src="~/Scripts/jquery.validate.js"></script>

<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

Ta khai báo thư viện jQuery validate trong section scripts được định nghĩa trong
layout là kỹ thuật quản lý các đoạn mã javascript trong ứng dụng MVC, và nhằm đảm
bảo thư viện jQuery validate được khai báo sau thư viện jQuery.

Rebuild và chạy lại View Create, không nhập liệu gì cả nhấn vào nút lưu lại.
Một thông báo lỗi được hiện ra

Chúng ta có thể dùng CSS để định dạng màu thông báo lỗi để người dùng dễ
quan sát hơn

6.4. Sửa dữ liệu


Chúng tôi đã phân tích và hướng dẫn khá kỹ việc thêm mới dữ liệu. Việc sửa
dữ liệu hoàn toàn tương tự.

Đầu tiên chúng ta cần lấy được dữ liệu cần sửa, sau đó hiển thị lên View để
người dùng sửa rồi cập nhật lại CSDL

Action Edit

[HttpGet]

public ActionResultEdit(int id)

returnView(db.Students.Find(id));

[HttpPost]

public ActionResultEdit(Student model)

if(ModelState.IsValid)

44
{

db.Entry(model).State = System.Data.Entity.EntityState.Modified;

db.SaveChanges();

returnRedirectToAction("Index");

returnView(model);

Tương tự Create, Edit cũng có 2 action tương ứng là get và post, tham số phương
thức Get là id của Student để tìm ra Student cần thay đổi.Tham số phương thức post
tương tự tham số trường hợp create.(đây là 1 phương thức của Linq)

Lệnh db.Student.Find(id) lấy về Student có id là tham số được truyền vào

Lệnh db.Entry(model).State = System.Data.Entity.EntityState.Modified; dùng


để thay đổi thông tin 1 bản ghi trong đối tượng Context

Lệnh db.SaveChanges(); để lưu lại các thay đổi xuống dưới CSDL.

View Edit

Code do Visual Studio sinh ra

@model SampleMVC.Models.Student

@{

ViewBag.Title = "Edit";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Edit</h2>

@using (Html.BeginForm())

@Html.AntiForgeryToken()

<div class="form-horizontal">

<h4>Student</h4>
45
<hr />

@Html.ValidationSummary(true, "", new { @class = "text-danger" })

@Html.HiddenFor(model => model.ID)

<div class="form-group">

@Html.LabelFor(model => model.Name, htmlAttributes: new {


@class = "control-label col-md-2" })

<div class="col-md-10">

@Html.EditorFor(model => model.Name, new { htmlAttributes


= new { @class = "form-control" } })

@Html.ValidationMessagentitype frameworkor(model =>


model.Name, "", new { @class = "text-danger" })

</div>

</div>

<div class="form-group">

<div class="col-md-offset-2 col-md-10">

<input type="submit" value="Save" class="btn btn-dentitype


frameworkault" />

</div>

</div>

</div>

Tương tự View Create, chúng ta sửa lại View Edit cho mã đơn giản hơn như
sau:

@model SampleMVC.Models.Student

@{

46
ViewBag.Title = "Edit";

Layout = "~/Views/Shared/_Layout.cshtml";

@using (Html.BeginForm())

@Html.ValidationSummary(true)

@Html.HiddenFor(m=>m.ID)

@Html.LabelFor(m => m.Name)

<div>

@Html.EditorFor(m => m.Name)

@Html.ValidationMessagentitype frameworkor(m => m.Name)

</div>

<p>

<input type="submit" value="Lưu lại" />

</p>

Chạy View Edit có khác View Create và Index 1 chút đó là cần truyền tham số.

Giả sử ta muốn thay đổi Student có id là 1 thì gọi lệnh sau:

/Sample3/Edit/1

Get Edit action được gọi, sau khi thay đổi nội dung, nhấn save, lại những thông
tin thay đổi sẽ được lưu lại dưới CSDL. Và ứng dụng được điều hướng tới trang Index

6.5. Dùng chung View Create và Edit


Một nhận xét nhỏ đó là View Create và Edit khá tương đồng nhau, và để tránh
trùng lặp code khi phải tạo tới 2 View, thì ta chỉ tạo 1 View. Giả sử tên View là Editor.

47
Khi này các Action Create, Edit thay vì trả về Create, Edit View thì sẽ cùng trả
về Editor View

Controller:

// Create:

[HttpGet]

public ActionResultCreate()

returnView("Editor");

[HttpPost]

public ActionResultCreate([Bind(Exclude = "ID")]Studentmodel)

if(ModelState.IsValid)

db.Students.Add(model);

db.SaveChanges();

returnRedirectToAction("Index");

returnView("Editor",model);

Edit:

[HttpGet]

public ActionResultEdit(int id)

returnView("Editor", db.Students.Find(id));

48
[HttpPost]

public ActionResultEdit(Student model)

if(ModelState.IsValid)

db.Entry(model).State = System.Data.Entity.EntityState.Modified;

db.SaveChanges();

returnRedirectToAction("Index");

returnView("Editor", model);

View Editor sẽ như sau:

@model SampleMVC.Models.Student

@{

ViewBag.Title = "Editor";

Layout = "~/Views/Shared/_Layout.cshtml";

@using (Html.BeginForm())

@Html.ValidationSummary(true)

@Html.HiddenFor(m => m.ID)

@Html.LabelFor(m => m.Name)


<div>
@Html.EditorFor(m => m.Name)
@Html.ValidationMessagentitype frameworkor(m => m.Name)
</div>

49
<p>
<input type="submit" value="Lưu lại" />
</p>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

Ta thấy thay vì phải tạo 2 View gây rối mã nguồn, chúng ta có thể tạo 1 View
dùng chung cho cả 2 Action khá tiện lợi.

6.6. Xóa dữ liệu


Việc xóa dữ liệu trong Entity Framework cũng khá đơn giản, được hiện thực
thông qua 2 Action sau:

[HttpGet]
public ActionResultDelete(int id)
{
returnView(db.Students.Find(id));
}
[HttpPost, ActionName("Delete")]
public ActionResultDeleteConfirmed(int id)
{
var _student = db.Students.Find(id);
db.Students.Remove(_student);
db.SaveChanges();

returnRedirectToAction("Index");

// Chú ý Action Delete đều nhận vào tham số kiểu là int, nên quá tải phương
thức không cho phép, vì thể cần đặt tên cho ActionDelete phương thức post, hoặc get
khác nhau.Ở đây ta đổi tên phương thức post là: DeleteConfirmed, và dùng 1 Attribute
chỉ định tên Action vẫn là delete
50
// Khác với Action khác trả về 1 View, Action delete ta redirect (điều hướng )
về Action Index

View Delete:

Tạo view Delete tương tự Edit, Create.Chọn template là Delete

@model SampleMVC.Models.Student

@{

ViewBag.Title = "Delete";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Delete</h2>

<h3>Are you sure you want to delete this?</h3>

<div>

<h4>Student</h4>

<hr />

<dl class="dl-horizontal">
<dt>
@Html.DisplayNamentitype frameworkor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
</dl>
@using(Html.BeginForm()) {
@Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-dentitype
frameworkault" /> |

51
@Html.ActionLink("Back to List", "Index")
</div>
}
</div>
View Delete chủ yếu thông báo cho người dùng biết họ đang xóa Student nào

Tương tự View Edit ta cần truyền tham số khi gọi Action Delete, giả sử cần xóa
Student có id là 3 thì gọi bằng url sau: /sample3/Delete/3

Nhấn vào button Delete thì Student sẽ bị xóa khỏi CSDL

6.7. Xem chi tiết dữ liệu


// Action details dùng xem chi tiết 1 student
Action Details:
public ActionResultDetails(int id)
{
returnView(db.Students.Find(id));
}
View Details
@model SampleMVC.Models.Student
@{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Details</h2>
<div>
<h4>Student</h4>
<hr />
<dl class="dl-horizontal">
<dt>

52
@Html.DisplayNamentitype frameworkor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
@Html.ActionLink("Back to List", "Index")
</p>

6.8. Một vài vấn đề phát sinh trong xử lý CRUDs


Vấn đề 1:

Trong các View Create Edit tự động do mã máy tạo thường có khai báo
javascript sau:

@section Scripts {

@Scripts.Render("~/bundles/jqueryval")

hoặc khai báo tương tự trong MVC 3

<script src="~/Scripts/jquery.validate.js"></script>

<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

Đây là khai báo sử dụng 2 thư viện hỗ trợ validate khi nhập liệu.Ví dụ như 1
trường nhập liệu phải là số, hay trường không được để trống thì script tự động thông
báo lỗi.Việc định nghĩa các trường này được khai báo trong Model của của các đối
tượng. Giả sử ta có lớp Student như sau:

public class Student

public int ID { get; set; }

53
[Required(ErrorMessage = "không được rỗng")]

public string Name { get; set; }

[RegularExpression("[0-9]{1,5}", ErrorMessage = "Bạn phải nhập số")]

public intPhone { get; set; }

// khi create, edit đối tượng Student thì trường Name phải nhập (không được để
trống ).Trường Phone phải nhập số.Nếu không nhập đúng thì javascript sẽ báo lỗi
ngay.Đây là tính năng validate hỗ trợ thiết kế model.

còn rất nhiều attribute hỗ trợ thiết kế model như là định tên hiển thị 1 trường
(giúp ta hiển thị tên các trường kiểu tiếng việt ), template như tạo 1 ô textArea (ô
textBox lớn ), hay ckEditor để nhập liệu … Các tính năng này sẽ được học trong phần
định nghĩa CSDL với ENTITYPE FRAMEWORK code first.

Vấn đề 2: Trong các Action Create có các khai báo như sau:

[HttpPost]

public ActionResultCreate([Bind(Exclude = "ID")]Studentmodel)

db.Students.Add(model);

db.SaveChanges();

returnView();

// khai báo trên chỉ định không kiểm tra (validate) trường ID vì khi create thì
trường ID ta để tự động tăng và không cần nhập dữ liệu này trên View.

Hoặc có 1 khai báo code tương tự như sau:

ModelState.Remove("ID");

Vấn đề 3: Việc xử lý các bảng chứa mối quan hệ

Giả sử có 2 bảng Product (sản phẩm ) và bảng Category (loại sản phẩm ) 2 bảng
này có mối quan hệ 1 – n với nhau.Việc CRUD có đôi chút khác so với bảng Student ở
trên.Và được học cụ thể trong phần tiếp

54
BÀI 7. TH 2 TẠO VÀ KẾT NỐI CƠ SỞ DỮ LIỆU SỬ
DỤNG ENTITY
Bài 1. Tạo 1 cơ sở dữ liệu về website tin tức và thực hiện các yêu cầu sau:

- Thực hiện tạo Entitype kết nối tới cơ sở dữ liệu tin tức vừa tạo được
- Sử dụng các class trong Entitype tạo được để thực hiện việc nhập, sửa, xóa,
hiển thị dữ liệu ra mà hình
- Kết hợp dữ liệu với các điều khiển Dropdownlist
- Thực hiện tìm kiếm bản tin
- Thực hiện xuất dữ liệu theo phân loại

Bài 2. Thực hiện tạo một cơ sở dữ liệu website bán hang và thực hiện các yêu
cầu

- Thực hiện tạo Entitype kết nối tới cơ sở dữ liệu tin tức vừa tạo được

55
- Sử dụng các class trong Entitype tạo được để thực hiện việc nhập, sửa, xóa,
hiển thị dữ liệu ra mà hình
- Kết hợp dữ liệu với các điều khiển Dropdownlist
- Thực hiện tìm kiếm bản tin
- Thực hiện xuất dữ liệu theo phân loại

56
BÀI 8. THAO TÁC VỚI CƠ SỞ DỮ LIỆU TRONG
MVC
8.1. Tương tác dữ liệu từ Controller sang View
Trong các ví dụ trước chúng tôi đã hướng dẫn khá chi tiết việc tạo từ Model,
Controller tới View.

Trong các ví dụ tiếp theo để kiểm tra 1 tính năng hay kiến thức nào đó bạn có
thể tự tạo các Controller, View hoặc Model tương ứng để thực hành.

Để đơn giản chúng tôi không chi tiết lại cách tạo các đối tượng này mà chỉ
hướng dẫn thông qua mã nguồn.

Có hai cách truyền dữ liệu trực tiếp giữa Controller và View đó là truyền thông
qua lớp Model, ViewModel hoặc ViewBag

(1) Truyền bằng Model:

Trong các Action thì sẽ trả về (return) 1 View kèm theo dữ liệu.

Dữ liệu trả về có thể là kiểu dữ liệu giá trị (string, int …), lớp đối tượng (student,
Product …), hay kiểu Collection như array, List<T> … Ví dụ:

Controller:

public ActionResultAction1()

returnView(List<T>);

List<T> ở đây là thể hiện cụ thể của đối tượng Collection

Trong View khai báo biến Model cũng có kiểu là List<T> như sau:

@model IEnumable<T>

Khai báo IEnumable<T> tổng quát cho mọi đối tượng Collection trong đó có cả
lớp List<T> hiện thực interface này. Thường ta phải khai báo thêm cả namespace của
lớp T.

Trong các ví dụ trước chúng ta đã xem cách truyền dữ liệu từ Controller sang
View thông qua model cụ thể như sau

Controller:

57
public ActionResultIndex()

returnView(Person.GetData(10));

Action trả về danh sách dạng List<Person> và được truy vấn trong View
Index thông qua biến model như sau:

View

@model IEnumerable<SampleMVC.Models.Person>

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<table class="table">

<tr>

<th>

@Html.DisplayNamentitype frameworkor(model => model.Name)

</th>

</tr>

@foreach (var item in Model) {

<tr>

<td>

@Html.DisplayFor(modelItem => item.Name)

</td>

</tr>

58
}

</table>

(2) Truyền bằng ViewBag

Ví dụ trên Action trả về 1 đối tượng Model là List<Person>, giả sử chúng ta


muốn Action trả về nhiều đối tượng khác nữa, giả sử là List<Student> … thì chúng ta
dùng đối tượng ViewBag

ViewBag là 1 đối tượng Dynamic, có thể gán cho chúng bất kỳ kiểu dữ liệu nào,
và trong View có thể gọi trực tiếp chúng thông qua tên.

Trong 1 vài trường hợp trong View xử lý ta cần ép kiểu ViewBag để xử lý.

Giả sử Action khai báo như sau:

public ActionResultAction2()

ViewBag.Message = "Hello world";

returnView(Person.GetData(10));

// trong View tương ứng đọc giá trị ViewBag như sau:

@ViewBag.Message

Ở đây ta dùng ViewBag để truyền dữ liệu kiểu giá trị thông thường (int, string
).Với các kiểu tham chiếu như Product, List<Person> ta cần ép kiểu chính xác khi sử
đọc giá trị ViewBag từ View (Do ViewBag kiểu dữ liệu là Dynamic ). Trong View
Index có khai báo sau:

@foreach (Person item in (List< Person >) ViewBag.Persons)

// code sử lý

// chú ý khai báo NameSpace chứa class Person trong View Index ví dụ như:

@using SampleMvc.Models

59
(3) Truyền dữ liệu dùng ViewModel

Có 1 giải pháp thay thế dùng ViewBag đó là dùng ViewModel khi muốn truyền
nhiều kiểu dữ liệu từ Controller sang View

Giả sử chúng ta muốn truyền cả 2 List Person và Student sang View thì ta tạo
thêm 1 lớp ViewModel như sau:

public class PersonStudentVM

public IEnumerable<Person> Persons { get; set; }

public IEnumerable<Student> Students { get; set; }

Lớp PersonStudentVM thường đặt trong thư mục ViewModel

Controller:

public ActionResultAction1()

var_PersonStudentVM = new PersonStudentVM {

Persons = Person.GetData(10),

Students = Student.GetData(10)

};

returnView(_PersonStudentVM);

View chỉ cần khai báo model là đối tượng PersonStudentVM và tham chiếu tới
2 thuộc tính Students và Persons thông thường như sau:

@model SampleMVC.ViewModel.PersonStudentVM

@{

ViewBag.Title = "View";

Layout = "~/Views/Shared/_Layout.cshtml";

}
60
@foreach (var item in Model.Students)

// Code xử lý

@foreach (var item in Model.Persons)

// Code xử lý

8.2. Post dữ liệu dùng Model – View Model


Post dữ liệu dùng Model

Trong phần trước khi create, update đối tượng, dữ liệu được gửi lên server thông
qua model. Giả sử muốn gửi 1 Student lên Controller thì trong View sử dụng Model là
1 Student, và các giá trị này được khai báo trong 1 form như sau:

@model SampleMVC.Models.Student

@{

ViewBag.Title = "Editor";

Layout = "~/Views/Shared/_Layout.cshtml";

@using (Html.BeginForm())

@Html.ValidationSummary(true)

@Html.HiddenFor(m => m.ID)

@Html.LabelFor(m => m.Name)

<div>

@Html.EditorFor(m => m.Name)

@Html.ValidationMessagentitype frameworkor(m => m.Name)

61
</div>

<p>

<input type="submit" value="Lưu lại" />

</p>

Khi này razor sẽ tạo ra mã html là 1 thẻ form như sau:

<form action="/sample3/create" method="post"> <fieldset>

</form>

Ở đây form gọi chính Action trong Controller hiện tại, form muốn gọi Action
của Controller bất kỳ cần khai báo thẻ Action của form.

Tất cả các thẻ input trong form sẽ được gửi lên Controller, và Controller chỉ cần
khai báo 1 tham số kiểu Model (Student) để tiếp nhận dữ liệu như sau:

[HttpPost]

public ActionResultCreate(Student model)

returnView();

Post dữ liệu dùng ViewModel

Ở trên ta có sẵn lớp Model là class Student, trong các trường hợp ta muốn tạo
View mà chưa có model, thì ta tạo 1 Model hỗ trợ tạo View, thường gọi các lớp này là
kiểu ViewModel.

Giả sử ta muốn tính toán tổng 2 số, bằng cách post 2 số lên controller thì khai
báo ViewModel như sau:

public class SumNumberVM

public intNumber1 { get; set; }

public intNumber2 { get; set; }

62
}

// View khai báo sử dụng class SumNumberVM tương tự sử dụng với model
Product.

Controller:

[HttpGet]
public ActionResultIndex()
{
returnView();
}
[HttpPost]
public ActionResultIndex(SumNumberVM model)
{
ViewBag.Sum = model.Number1 + model.Number2;
returnView();
}
View:
@model SampleMVC.ViewModel.SumNumberVM
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>SumNumberVM</legend>

<div class="editor-label">
@Html.LabelFor(model => model.Number1)
63
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Number1)
@Html.ValidationMessagentitype frameworkor(model =>
model.Number1)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Number2)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Number2)
@Html.ValidationMessagentitype frameworkor(model =>
model.Number2)
</div>
<p>
<input type="submit" value="Tính Tổng" />
</p>
</fieldset>
}
<h1>@ViewBag.Sum</h1>
@section Scripts {

@Scripts.Render("~/bundles/jqueryval")

8.2.1 Post dữ liệu dùng Model


Ở phần trên ta khai báo Action có tham số là cả lớp Model, tuy nhiên trong 1
vài trường hợp ta khai báo Action có tham số là tên hoặc biến FormCollection thông
qua các thẻ input trên form nhập liệu

64
Razor View Engine hỗ trợ có hỗ trợ tự động tạo thẻ form (các ví dụ về create,
hay tính tổng có dùng Html.BeginForm()). Các ví dụ dưới đây tạo các form thuần bằng
html để các bạn thấy sự mềm dẻo của Razor View Engine trong việc code và xử lý
html.

Controller nhận tham số theo tên input trên form nhập liệu:

[HttpGet]

public ActionResultIndex()

returnView();

[HttpPost]

public ActionResultIndex(string Name)

ViewBag.Name ="Xin chào bạn:"+ Name;

returnView();

View:

Có thể khai báo dùng Html.BeginForm như các ví dụ trước

Để hiểu bản chất mã html ta khai báo theo kiểu html thuần như sau:

Chú ý tên của input text phải trùng tên tham số của Action

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

@ViewBag.Name

<form action="/sample6/index" method="post">

<div>
65
Nhập Tên: <input type="text" name="Name" />

</div>

<input type="submit" value="Post dữ liệu" />

</form>

8.2.1 Post dữ liệu dùng View Model


Với việc post dữ liệu theo tên thẻ input ở phần trên (9.3) thì Action chỉ nhận 1
giá trị tham số.Với việc post nhiều giá trị thì yêu cầu Action cần nhiều tham số.Ta có
thể khai báo 1 biến kiểu FormCollection tổng quát rồi truy vấn tới các giá trị input thông
qua tên của chúng như ví dụ sau:

View:

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

@ViewBag.FullName

<form action="/Sample7/Index" method="post">

<div>

Tên Họ:<input type="text" name="Number1" />

</div>

<div>

Tên Gọi:<input type="text" name="Number2" />

</div>

<input type="submit" value="Tính Tổng" />

</form>

Controller

[HttpGet]

66
public ActionResultIndex()

returnView();

[HttpPost]

public ActionResultIndex(FormCollection frm)

ViewBag.FullName = frm["Number1"]+ "-"+frm["Number2"];

returnView();

// Khi dùng FormCollection có thể lấy dữ liệu từ nhiều Control trên Form.

8.2.1 Controller
Chạy ứng dụng, gọi Sample7Controller (/sample7) được kết quả như hình sau:

// Khi dùng FormCollection có thể lấy dữ liệu từ nhiều Control trên Form.

8.3. Post dữ liệu dùng tên thẻ input


Với việc post dữ liệu theo tên thẻ input ở phần trên (9.3) thì Action chỉ nhận 1
giá trị tham số.Với việc post nhiều giá trị thì yêu cầu Action cần nhiều tham số.Ta có
thể khai báo 1 biến kiểu FormCollection tổng quát rồi truy vấn tới các giá trị input thông
qua tên của chúng như ví dụ sau:

67
View:

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

8.4. Post dữ liệu dùng FormCollection


Controller

[HttpGet]

public ActionResultIndex()

returnView();

[HttpPost]

public ActionResultIndex(FormCollection frm)

ViewBag.FullName = frm["Number1"]+ "-"+frm["Number2"];

returnView();

68
BÀI 9. TẠO LIÊN KẾT CƠ SỞ DỮ LIỆU VỚI
EMTITY FRAMEWORK
9.1. Bảng dữ liệu chứa quan hệ trong EF code first
Thường 1 ứng dụng các bảng dữ liệu thường chứa mối quan hệ (1 – 1 ; 1 – n, n
– n ).

Trong thiết kế entitype framework code fist cũng hỗ trợ các mối quan hệ trên.

Xét ứng dụng quản lý sản phẩm chúng ta có 2 bảng:

Product (Sản phẩm)

Category (Loại sản phẩm)

Quan hệ giữa bảng Category và Product là 1 – n.Ta thiết kế lớp Product và


Category như sau:

public class Product

[Key]

public intProductID { get; set; }

public stringProductName { get; set; }

public intCategoryID { get; set; }

public virtual CategoryCategory { get; set; }

public class Category

[Key]

public intCategoryID { get; set; }

public stringCategoryName { get; set; }

public virtual ICollection<Product> Products { get; set; }

69
// thêm class Category,Product vào lớp Entity

public class AppEntity:DbContext

public DbSet<Student> Students { get; set; }

public DbSet<Product> Products { get; set; }

public DbSet<Category> Categorys { get; set; }

protected override voidOnModelCreating(DbModelBuilder modelBuilder


)

modelBuilder.Conventions.Remove<PluralizingTableNameConventio
n>();

ta chú ý lớp Product và Category có thuộc tính vitual.Đây là thuộc tính sẽ không
tạo ra trường dưới CSDL.

Thuộc tính Category của lớp Product có kiểu dữ liệu là Category lưu trữ thông
tin 1 Category tương ứng với Product.

Thuộc tính Products của lớp Category có kiểu dữ liệu


là ICollection<Product> (có thể thay bằng List<Product> ) lưu trữ danh sách Product.

entitype framework tự động tạo ra các bảng trung gian trong các mối quan hệ n
– n.

Muốn truy vấn các Product của một loại Category nào chỉ cần truy vấn như sau:

db.Category.Products

Hay muốn truy vấn Category của 1 Product chỉ cần truy vấn như sau:

db.Product.Category

9.2. Tạo dữ liệu thao tác với Entity Framework


// tạo dữ liệu mặc định cho bảng category, Product trong file Dentitype
frameworkaultData

70
public class Dentitype
frameworkaultData: DropCreateDatabaseIfModelChanges<VinaEntity>
{
protected override voidSeed(VinaEntity context)
{
new List<Category> {
new Category { CategoryID=1, CategoryName="Category 1"},
new Category { CategoryID=2, CategoryName="Category 2"},
new Category { CategoryID=3, CategoryName="Category 3"}

}.ForEach(m => context.Categorys.Add(m));


new List<Product> {
new Product{ ProductID =1, CategoryID=1, ProductName="Product
1"},
new Product{ ProductID =2, CategoryID=1, ProductName="Product
2"},
new Product{ ProductID =3, CategoryID=2, ProductName="Product
3"},
new Product{ ProductID =4, CategoryID=2, ProductName="Product
4"}
}.ForEach(m => context.Products.Add(m));
}
}
Tạo CategoryController:
// tạo 2 Action là Index, và Details để hiển thị danh sách Category và xem chi
tiết 1 Category
public class CategoryController: Controller
{
VinaEntity db = new VinaEntity();
public ActionResultIndex()

71
{
returnView(db.Categorys);
}
public ActionResultDetails(int id)
{
returnView(db.Categorys.Find(id));
}
}
Tạo View Index và Details:

Tạo View Index và Details bình thường để VS tự động sinh code.View Details
có 1 vài tùy chỉnh để lấy về danh sách Sản phẩm (Product) tương ứng với Loại sản
phẩm (Category) như sau:

Index:

<table>

<tr>

<th>

@Html.DisplayNamentitype frameworkor(model =>


model.CategoryName)

</th>

<th></th>

</tr>

@foreach (var item in Model) {


<tr>
<td>
@Html.DisplayFor(modelItem => item.CategoryName)
</td>
<td>
@Html.ActionLink("Details", "Details", new { id=item.CategoryID })
72
</td>
</tr>
}
</table>
Details:
<fieldset>
<legend>Category</legend>

<div class="display-label">
@Html.DisplayNamentitype frameworkor(model =>
model.CategoryName)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.CategoryName)
</div>
</fieldset>
@*Thêm đoạn mã sau *@
<h1>Danh sách sản phẩm</h1>
<table>

<tr>

<td>Tên Sản Phẩm</td>

</tr>

@foreach (var item in Model.Products)

<tr>

<td> @Html.DisplayFor(modelItem => item.ProductName)</td>

</tr>

73
}

</table>

Chạy ứng dụng và gọi Sample8Controller (/sample8) được kết quả danh sách
loại sản phẩm (category)

Mối khi nhấn details link thì Action Details được gọi sẽ hiển thị các thông tin
chi tiết về Category và các Product thuộc Category.Tức là ta đã truy vấn được tới bảng
Product có mối quan hệ với bảng Category.Giả sử ta nhấn vào nút Detail của Category2
được

74
BÀI 10. TH 3. TRUYỀN DỮ LIỆU GIỮA CÁC THÀNH
PHẦN CỦA MVC
12.1. Viết lệnh phía server

Yêu cầu: Kiểm tra dữ liệu nhập ở bài trước (Nhập hồ sơ cán bộ), đảm bảo các
yêu cầu sau:

- Họ tên không được rỗng, chỉ chứa chữ cái và dấu cách. Độ dài <= 30;

- Ngày tháng năm sinh phải hợp lệ. Ví dụ tháng 2 của năm nhuận có 29
ngày, các

- năm khác là 28 ngày.

- Ngày sau phải "lớn hơn" ngày trước. Ví dụ ngày xuất ngũ phải trước
ngày nhập

- ngũ.

- Các trường số chỉ chứa giá trị là số dương, không chứa ký tự


thôngthường.

- Các ô textbox nhiều dòng, chứa tối đa là 1000 ký tự.

- Chừng nào dữ liệu còn nhập sai thì cần phải focus đến đó để yêu cầu
người dùng sửa lại.

- Nếu mọi dữ liệu nhập đều hợp lệ thì gửi ẩn các điều khiển và chỉ một
dòng thông báo là : "Hồ sơ đã được cập nhật" ra giữa màn hình !.

Hướng dẫn:

Để đọc giá trị value của mục đang được chọn trong DropDownList thì viết:
DDL_Name.Text . Trong đó: DDL_Name là id của dropdownlist.

- Để truy xuất tới một phần tử có chỉ số i trong Dropdownlist, viết:


DDL_Name.Items[i];

- Để xóa các mục: DDL_Name.Clear(); để đếm số mục :


DDL_Name.Count;

- Để thêm một mục vào DDL (Dropdownlist)

- DS.Items.Add ("Mục mới"); Hoặc

- DS.Items.Add (new ListItem ("text", "value"));

- Hàm chuyển ngày tháng dạng xâu sang kiểu Date: DateTime d;

75
- DateTime D = DateTime.Parse (s);

- int D.Day; D.Month; D.Year €trả về ngày, tháng năm của D.

- Để focus tới một phần tử: Viết <Giá trị ID>.Focus(); VD: DS.Focus();

- Phép toán lấy phần nguyên, phần dư:

- Lấy nguyên: 20/ 6 €3

- Lấy phần dư: 20 % 6 € 2

Sử dụng một số điều khiển Ajax Control Toolkit

Cách đăng ký và đưa Ajax Control Toolkit vào dự án:

Cần có 3 file sau:

Bước 1, vào menu website €Add Reference €Chọn Tab Browse. Sau đó chọn 2
tệp

(1) và (2) ở trên. Click OK.

Bước 2: Click chuột phải lên hộp toolbox và chọn "Choose Items". Khi hộp
thoại mở ra, Browse tới file (3) ở trên. Click OK.

Sử dụng Calendar

Yêu cầu: Viết một trang cho phép người dùng nhập vào ngày sinh của họ. Ngày
sinh này được nhập bằng cách chọn trực tiếp trên lịch (Canlendar).

<%@ Page Language="C#" AutoEventWireup="true"


CodeFile="Default3.aspx.cs" Inherits="Default3" %>

<%@ Register Assembly="AjaxControlToolkit"


Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>Calendar</title>

76
</head>

<body>

<form id="form1" runat="server">

<asp:ScriptManager ID="ScriptManager1" runat="Server"


EnableScriptGlobalization="true" EnableScriptLocalization="true" />

<b>Nhập ngày sinh:</b>

<asp:TextBox runat="server" ID="txtNS"></asp:TextBox>

<ajaxToolkit:CalendarExtender ID="cal" TargetControlID="txtNS"


runat="server" >

</ajaxToolkit:CalendarExtender>

</form>

</body>

</html>

Lưu ý:

Trong thẻ <ajaxToolkit:CalendarExtender ID="cal" TargetControlID="txtNS"


runat="server" >. Thuộc tính TargetControlID cho biết là sẽ hiển thị Calendar khi người
dùng focus điều khiển có id là txtNS.

o Trong trang cần phải có thẻ <asp:ScriptManager và đặt trong thẻ Form.

Nhập ngày tháng theo định dạng (sử dụng điều khiển MaskedEdit extender)

<%@ Page Language="C#" AutoEventWireup="true"


CodeFile="MaskedEdit.aspx.cs" Inherits="MaskedEdit" %>

<%@ Register Assembly="AjaxControlToolkit"


Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>Maskedit</title>

77
</head>

<body>

<form id="form1" runat="server">

<asp:ScriptManager ID="SM1" runat="server"


EnablePartialRendering="True" /> Nhập ngày tháng theo dạng: MM/dd/yyyy (culture
sensitive)<br />

<asp:TextBox ID="TextBox1" runat="server" Width="130px"


ValidationGroup="Demo1" MaxLength="1" style="text-align:justify" />

<ajaxToolkit:MaskedEditExtender ID="MaskedEditExtender1" runat="server"


TargetControlID="TextBox1" Mask="99/99/9999"

MessageValidatorTip="true" MaskType="Date" DisplayMoney="Left"

AcceptNegative="Left" />

<ajaxToolkit:MaskedEditValidator ID="MaskedEditValidator1"
runat="server" ControlExtender="MaskedEditExtender1"
ControlToValidate="TextBox1"

IsValidEmpty="False" EmptyValueMessage="Phải nhập ngày tháng"


InvalidValueMessage="Ngày tháng nhập sai" ValidationGroup="Demo1"
Display="Dynamic" TooltipMessage="Nhập vào một ngày" />

</form>

</body>

</html>

** Chú ý: Trường hợp này cần phải đặt 2 điều khiển Ajax, một cái là
ajaxToolkit:MaskedEditExtender và một cái là ajaxToolkit:MaskedEditValidator. Cái
thứ hai cần phải gắn với cái thứ nhất bằng cách đặt thuộc tính ControlExtender.

78
BÀI 11. GIỚI THIỆU RAZOR VIEW ENGINE
11.1. Lớp SelectListItem và SelectList
C# hỗ trợ 2 lớp thường được sử dụng để tạo nguồn cho dropdowlist (có thể sử
dụng vào các mục đích khác )

SelectListItem:

public class SelectListItem

{ public bool Selected { get; set; }

public string Text { get; set; }

public string Value { get; set; }

Ta thấy SelectListItem có các thuộc tính Text (giá trị được hiển thị ) Value (giá
trị thực sự được lấy khí lựa chọn ) Và Selected là giá trị mặc định được chọn.

SelectList

public class SelectList: MultiSelectList

public SelectList(IEnumerableitems);

public SelectList(IEnumerableitems, object selectedValue);

public SelectList(IEnumerableitems, string dataValuentitype


frameworkield, stringdataTextField);

public SelectList(IEnumerableitems, string dataValuentitype


frameworkield, stringdataTextField, object selectedValue);

public object SelectedValue { get; }

SelectList thực ra là 1 danh sách SelectListItem, có nhiều kiểu khởi tạo.Nhưng


bản chất chủ yếu là truyền vào 1 danh sách đối tượng, chọn thuộc tính hiển thị, thuộc
tính giá trị khi được chọn và thuộc tính chọn mặc định

11.2. Dùng lớp SelectList tạo nguồn dữ liệu Dropdowlist trong MVC
Mã Html định nghĩa dropdowlist như sau:
79
<select>

<option value="Value1">textValue1</option>

<option value="Value2" selected="selected">textValue2</option>

<option value="Value3">textValue3</option>

</select>

Mục đích của chúng ta là lấy dữ liệu động từ CSDL hiển thị lên Dropdowlist.

Giả sử ở đây ta muốn thêm mới 1 sản phẩm (Product) và cần gán sản phẩm này
(Product) đang thuộc loại sản phẩm nào (Category)

// GET: /Sample9/

AppEntity db = new AppEntity();

[HttpGet]

public ActionResultIndex()

ViewBag.CategoryID
= new SelectList(db.Categorys, "CategoryID", "CategoryName");

returnView();

[HttpPost]

public ActionResultIndex(Product model)

// xử lý thêm mới Product

returnView();

Chú ý tên của ViewBag đặt là CategoryID phải đặt giống trường của bảng chứa
mối quan hệ, để khi chạy view Razor tự động sinh ra thẻ html select có tên trùng với
tên trường là CategoryID để post lên server

80
View Index ta khai báo như sau:

Các thuộc tính khác khai báo thông thường, thuộc tính Category ta tạo
Dropdowlist như mã sau:

<h2>Index</h2>

@using (Html.BeginForm())

@Html.ValidationSummary(true)

<fieldset>

<legend>Product</legend>

<div class="editor-label">

@Html.LabelFor(model => model.ProductName)

</div>

<div class="editor-field">

@Html.EditorFor(model => model.ProductName)

@Html.ValidationMessagentitype frameworkor(model =>


model.ProductName)

</div>

<div class="editor-label">

@Html.LabelFor(model => model.CategoryID)

</div>

<div class="editor-field">

@Html.DropDownList("CategoryID", String.Empty)

@*@Html.EditorFor(model => model.CategoryID)*@

@Html.ValidationMessagentitype frameworkor(model =>


model.CategoryID)

</div>

<p>
81
<input type="submit" value="Create" />

</p>

</fieldset>

@section Scripts {

@Scripts.Render("~/bundles/jqueryval")

Có thể khai báo DropdownList tường minh như sau:

@Html.DropDownListFor(m => m.CategoryID,


(SelectList)ViewBag. CategoryIDs, String.Empty)

Tên ViewBag cần khác tên thuộc tính của DropdownList

ta thấy mục CategoryID được chuyển thành 1 DropdowList để lựa chọn.Ở đây
ta không xử lý nút nhấn Create.Việc xử lý việc tạo Product tương tự việc xử lý tạo
Student như ở phần 6 và phần 7.

11.3. Các khái niện cơ bản về Razor


Các phiên bản MVC 3, MVC4,MVC5, Asp.net MVC có hỗ trợ 1 loại Engine
mới đó là Razor View Engine, bản MVC trước đó và webform chỉ hỗ trợ aspx Engine.

Một View Engine chủ yếu để sinh mã html động bằng cách lập trình.

Razor ViewEngine có code tương tự mã C# và vb.net.

Trong Razor ta có thể khai báo trực tiếp các thẻ html thông thường.Ngoài ra
Razor cung cấp rất nhiều HtmlHelper hỗ trợ tự động sinh mã html.

Nói tóm gọn là Razor View Engine có cách code như code mã.net (C#, vb.net )
và html làm cho việc thiết kế View động trở nên đơn giản và dễ nhìn hơn.

Những gì được khai báo trong Razor (các file.cshtml hoặc.vbhtml): Gồm các
mã Razor (cấu trúc tương tự C#), các thẻ html thuần, các Html Helper.Các Html Helper
thực ra là các thư viện của Razor hỗ trợ lập trình mvc tạo ra các mã html.Vì thể để hiểu
bản chất các html helper chúng ta nên xem mã html cuối cùng mà mvc tạo ra.

11.4. Viết mã Razor


Trong razor có thể viết mã html thông thường như sau:

82
<div>

<h1>Hello worl</h1>

</div>

Viết mã Razor có cấu trúc như mã C# (hoặc vb.net ).Được khai báo sau ký tự @.

@{

stringHello = "Hello world";

<h1>@Hello</h1>

11.5. Html Helper Control


Razor hỗ trợ tạo mã html phần lớn các Control Html như: label, textBox,
RadioButton, Dropdowlist

Chú yếu các Helper Control dùng vào việc hiển thị dữ liệu được load từ CSDL
rồi tự động sinh (generate) mã html tương ứng.

Ví dụ

Control thường:

@Html.TextBox("") // sinh mã html thẻ input text

@Html.DropDownList("") // thẻ select

Control hiển thị dữ liệu:

tạo 1 textBox nhập nội dung ProductName

@Html.EditorFor(model => model.ProductName)

Tạo Label hiển thị nội dung

@Html.LabelFor(model => model.ProductName)

Tạo giá trị hiển thị trực tiếp

@Html.DisplayFor(modelItem => item.CategoryName)

83
// Một thẻ rất hay dùng trong MVC đó là ActionLink

11.6. ActionLink
ActionLink là HtmlHelper của mvc sinh ra 1 thẻ a (html ).ActionLink thường
được tạo ra các thẻ link gọi tới các Action của Controller

Action Link

// Gọi tới Action của Controller bất kỳ.Chú ý cần có tham số null cuối cùng

@Html.ActionLink("Tên hiển thị", "ActionName", "ControllerName", new {


id = item.UserName }, null)

// Action chứa html Attribute:

@Html.ActionLink("Xóa", "Delete", "Product", null, new { @class


= "linkButton2" })

// chứa parameter:

@Html.ActionLink("Sửa",

"Edit",

"Product",

new { id = item1.ProductID },

new { @class = "linkButton2" })

// Gọi tới Action của Controll hiện tại

@Html.ActionLink("Details", "Details", new { id = item.UserName })

// Với nhứng thẻ a cần tạo nhiều thuộc tính html để xử lý css, jQuery thì có thể
tạo theo cú pháp sau để gọi tới các Controller

Url.Action – Url.Content

<a hrentitype framework="@Url.Action("Index",


"Home")">@item.TenNhanVien</a>

@Url.Action("Action","Controller")

@Url.Content("~/"+ Model.Image)

// Ngoài ra Html.ActionLink cũng hỗ trợ tạo các thuộc tính của html cho thẻ a
như sau:
84
ActionLink render event OnClick,Property Html

@Html.ActionLink("Xóa", "Delete",null, new {

onclick = "return confirm('bạn có thực sự muốn xóa không ?');"})

Html.ActionLink(

"Create New",

"Create",

CONTROLLERNAME,

null,

new { @class= "yourCSSclass", @style= "width:100px; color: red;" }

// trường hợp có tham số:

@Html.ActionLink("Sửa", "Edit", null, new {id = Model.Id }, new {@class


= "LinkButton" })

// Các bạn hãy thử tạo các Control này trong View và xem mã html MVC tạo ra
để hiểu bản chất các đối tượng mà RazorView tạo ra.

11.7. Đối tượng Helpers và Functions trong Razor code


Như đã trao đổi phần trước Razor code hỗ trợ ngôn ngữ C#, vb.net ngay trong
trang.cshtml hay.vbhtml

Ngoài ra Razor code còn hỗ trợ khai báo namespace để tham chiếu tới các thư
viện bên ngoài trang.cshtml hay.vbhtml

Razor cung cấp 2 đối tượng Helpers và Functions như là các hàm, phương thức
xử lý mã html và C#

(1) Đối tượng functions

Chúng ta đã gặp đối tượng này trong phần giới thiệu về lập trình OOP trong
Razor Code

Chúng ta có thể khai báo mã C# trong bổ từ khóa sau:

@functions{

85
// code C# ở đây

Razor Code không hỗ trợ đầy đủ các kiểu dữ liệu hay các thư viện.net, tu nhiên
trong mã @functions {} chúng ta có thể code mã C# để xây dựng các đối tượng, phương
thức trực tiếp trong mã C#

Để đơn giản mã Razor, từ ví dụ này chúng tôi sẽ dùng khai báo layout(để không
cần phải khai báo các mã html cơ bản như: html, doctype …). Các bạn xem hướng dẫn
sử dụng Layout ở phần trước

Ở đây chúng tôi sử dụng layout mặc định do Visual Studio tạo ra là:
_SiteLayout.cshtml. Chúng tôi đổi mã _SiteLayout.cshtml như sau:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8" />

<title>@Page.Title My ASP.NET Web Page</title>

<meta name="viewport" content="width=device-width" />

</head>

<body>

@RenderBody()

</body>

</html>

Đây là 1 layout đơn giản nhất, chỉ có 2 thành phần là Page.Title và RenderBody

Tạo mới thư mục Function_Helper để chứa file ví dụ.Tạo file


FunctionSample.cshtml trong thư mục này.

Ta tạo mới 1 lớp Product ngay trong file FunctionSample.cshtml như sau:

@functions{

public class Product

86
{

public int ID { get; set; }

public string Name { get; set; }

public static List<Product> GetData(int Count)

var _Products= new List<Product>();

for (int i = 1; i <= Count; i++)

_Products.Add(new Product{ ID=i, Name="Product"+i.ToString()});

return _Products;

Và hiển thị danh sách 10 Product như sau:

<table>

<tr>

<td>ID</td>

<td>Name</td>

</tr>

@foreach (var item in Product.GetData(10))

<tr>

<td>@item.ID</td>

<td>@item.Name</td>

87
</tr>

</table>

Mã toàn bộ file FunctionSample.cshtml như sau:

@{

Page.Title = "Title goes here";

Layout = "~/_SiteLayout.cshtml";

@functions{

public class Product

public int ID { get; set; }

public string Name { get; set; }

public static List<Product> GetData(int Count)

var _Products= new List<Product>();

for (int i = 1; i <= Count; i++)

_Products.Add(new Product{ ID=i, Name="Product"+i.ToString()});

return _Products;

<table>

88
<tr>

<td>ID</td>

<td>Name</td>

</tr>

@foreach (var item in Product.GetData(10))

<tr>

<td>@item.ID</td>

<td>@item.Name</td>

</tr>

</table>

Các bạn có thể thấy sự đơn giản trong cách tạo dữ liệu rồi hiển thị dữ liệu trong
Razor code.Trong các trường hợp lấy dữ liệu từ Entity Framework, linq to sql hay
ado.net chúng ta làm tương tự

Ngoài cách khai báo trực tiếp trên Razor Code cũng hỗ trợ tạo lớp C# bên ngoài
hoặc tham chiếu từ thư viện DLL

Giả sử chúng ta có thể tạo lớp Product bên ngoài như sau:

+) Tạo thư mục App_Code: Chuột phải vào Project

+) Tạo file Product.cs trong thư mục App_Code (các bạn có thể tạo trong thư
mục bất kỳ, nhưng ở đây chúng ta tạo tại thư mục App_code để dễ dàng quản
lý)

Mã Visual Studio sinh cho lớp Product như sau:

using System;

usingSystem.Collections.Generic;

using System.Linq;

89
using System.Web;

public class Product

Ở đây lớp Product có namespace trùng với tên ứng dụng, và chúng ta có thể truy
cập trực tiếp trên mọi file.cshtml.

Chúng ta có thể tạo namespace để dễ dàng quản lý các tác vụ khác nhau của ứng
dụng (như các ứng dụng C# thông thường )

Giả sử ở đây chúng ta tạo namespace cho lớp Product là WebPageApp.Model,


code như sau:

using System;

usingSystem.Collections.Generic;

using System.Linq;

using System.Web;

namespace WebPageApp.Model

public class Product

Chúng ta viết mã lớp Product như đã viết ở phần trên như sau:

usingSystem.Collections.Generic;

namespace WebPageApp.Model

public class Product

{
90
public int ID { get; set; }

public string Name { get; set; }

public static List<Product> GetData(int Count)

var _Products = new List<Product>();

for (int i = 1; i <= Count; i++)

_Products.Add(new Product { ID = i, Name = "Product" +


i.ToString() });

return _Products;

Trở lại file FunctionSample.cshtml chúng ta code sử dụng lớp Product như sau:

@using WebPageApp.Model

@{

Page.Title = "Title goes here";

Layout = "~/_SiteLayout.cshtml";

<table>

<tr>

<td>ID</td>

<td>Name</td>

</tr>

@foreach (var item in Product.GetData(10))

91
{

<tr>

<td>@item.ID</td>

<td>@item.Name</td>

</tr>

</table>

Các bạn chú ý khai báo namespace tới lớp


Product: @using WebPageApp.Model

Và từ đây các bạn có thể hiểu là chúng ta có thể tham chiếu tới cả nhưng lớp
bên ngoài ứng dụng (các lớp trong thư viện dll động)

Đây là sức mạnh của Razor code, và chúng ta có thể tự xây dựng thư viện mô
hình lập trình cho riêng mình như MVC, MVVM theo phong cách riêng.Di nhiên chúng
ta sử dụng thư viện MVC sẵn do nhóm phát triển asp.net của Microsoft cung cấp là giải
pháp khá mạnh

(2) Đối tượng helpers

Chúng ta có thể viết các đoạn mã C# thông qua đối tượng @functions, để gọi
hoặc xử lý bằng mã C# ở nhiều nơi trong ứng dụng hoặc nhiều nơi trong file.cshtml

Razor code còn hỗ trợ viết các đoạn mã Razor code và sẽ được gọi tại nhiều
file.cshtml khác nhau hoặc các nơi khác nhau trong file.cshtml khai báo helpers

Với tính năng này chúng ta sẽ viết được rất nhiều đoạn mã html, javascript và
Razor code để gọi trong nhiều file.cshtml khác nhau.Hoặc chúng ta cũng có thể
download các file helpers được chia sẻ trên mạng để áp dụng vào project để đỡ mất
công viết lại các đoạn mã quen thuộc.

Các helpers hỗ trợ Web Page, MVC khá nhiều và quen thuộc như: facebook,
twiter, google … để tích hợp công cụ mạng này vào website của các bạn mà không phải
code html, javascript thuần

Kỹ thuật này khá quan trọng giúp mã ứng dụng trở nên gọn gàng và dễ bảo trì,
phát triển.

Ví dụ sau đây chúng ta tạo 1 Helper sinh mã html và Javascript rồi gọi chúng
ngay trong file.cshtml

92
Tạo mới file HelperSample.cshtml trong thư mục Function_Helper

Tạo Helper như sau:

@helper HelloHelper() {

<div>

<label>Nhập tên</label> <input type="text" id="txt1" />

</div>

<button onclick="GetHello()">Say Hello</button>

<script>

function GetHello() {

alert("Xin chào:" +txt1.value);

};

</script>

Mã Javascript khá đơn giản là đưa ra thông báo chào dựa vào tên nhập trong ô
textbox

Gọi và sử dụng helper:

<div>

@HelloHelper()

</div>

Mã toàn bộ file HelperSample.cshtml như sau (chú ý chúng tôi sử dụng file
_SiteLayout.cshtml)

@{

Page.Title = "Title goes here";

Layout = "~/_SiteLayout.cshtml";

@helper HelloHelper() {

93
<div>

<label>Nhập tên</label> <input type="text" id="txt1" />

</div>

<button onclick="GetHello()">Say Hello</button>

<script>

function GetHello() {

alert("Xin chào:" +txt1.value);

};

</script>

<div>

@HelloHelper()

</div>

Khá đơn giản, chúng ta thường viết các đoạn html, javascript và gọi chúng ở
các nơi khác nhau

Ngoài ra Razor code còn hỗ trợ viết mã Helpers trong 1 file riêng biệt và gọi
chúng ở nhiều nơi khác nhau

Để làm điều này chúng ta thêm 1 file helper trong thư mục App_Code

Ta soạn mã file MyHelper.cshtml như sau:

@helper HelloHelper()

<div>

<label>Nhập tên</label> <input type="text" id="txt1" />

</div>

<button onclick="GetHello()">Say Hello</button>

<script>

94
function GetHello() {

alert("Xin chào:" +txt1.value);

};

</script>

Sử dụng file helper đã khai báo như sau:

@{

Page.Title = "Title goes here";

Layout = "~/_SiteLayout.cshtml";

<div>

@MyHelper.HelloHelper()

</div>

Chạy ví dụ ta được kết quả tương tự như ví dụ trước:

Nhập tên vào textBox và nhấn button được kết quả như hình sau:

Với tính năng này chúng ta có thể tạo ra các HTML Control cho riêng mình như
những HtmlHelper mà Microsoft cung cấp

Các bạn có thể tìm hiểu thêm kỹ thuật dùng Helper tạo các Control hiển thị dữ
liệu hay xử lý trong tài liệu lập trình WebPage với Razor hay tài liệu kỹ thuật lập trình
MVC của chúng tôi để được hướng dẫn chi tiết cách tạo các Control riêng thường được
dùng khi phát triển các ứng dụng thực tế.

95
BÀI 12. IMPORT NỘI DUNG TRONG RAZOR CODE
12.1. Html.Partial
Html.Partial, Html.RenderPartial dùng để gọi 1 PartialView.PartialView là 1
loại View đặc biệt, chứa các thẻ html thuần hoặc các thẻ html chứa model hiển thị dữ
liệu (Action có thể trả về 1 PartialView )

Cấu trúc Html.Partial:

@Html.Partial("PartialView")

@Html.Partial("PartialView", Model)

Ví dụ:

Controller

public ActionResultIndex()

returnView();

// View Index:

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Nội dung View Index </h2>

@Html.Partial("PartialView1")

Tạo PartialView1 như sau:

Tại Folder: View/Sample10 right click chọn Add / View

// nhập nội dung cho PartialView như sau:

<h2>Nội dung lấy từ PartialView1</h2>

96
// Chạy ứng dụng và truy vấn tới Sample10Controller (/sample10)

Trường hợp nếu PartialView hiển thị nội dung theo 1 Model nào đó thì code
tương tự như 1 View thông thường.Khi gọi PartialView chỉ cần truyền vào tham số
Model theo cú pháp:

@Html.Partial("PartialView", Model)

// Ở đây PartialView đặt cùng thư mục View gọi nó.Có thể đặt PartialView tại
thư mục dùng chung Shared.

// Trường hợp gọi tới PartialView tại thư mục bất kỳ thì gọi theo cú pháp sau:

@Html.Partial("/Views/Sample1/PartialView1.cshtml")

Cú pháp trên gọi tới PartialView1 tại thư mục View/Sample1

12.2. RenderPartial
RenderPartial trả về 1 đối tượng Html

Cách dùng RenderPartial tương tự Html.Partial

Cú pháp:

@{Html.RenderPartial("_AddressPartial");}

// Thường ứng dụng RenderPartial trong trường hợp tạo View Create và Edit.Do
có chung cấu trúc nên chỉ cần tạo 1 PartialView sau đó từ View Create hay Edit sẽ gọi
PartialView này

12.3. Html.PartialView:
Dùng gọi tới 1 PartialView.PartialView này đã chứa các thẻ dùng Model định
nghĩa View

@Html.PartialView("PartialViewName")

Html.PartialView thường được gọi các PartialView có Model giống với kiểu
Model mà Controller trả về trong View gọi nó

12.4. Html.Action và Html.RenderAction


// Html.Action gọi tới các Action trả về kiểu string (Html.Action là Function
Method)

97
// Html.RenderAction là 1 Sub Method,gọi tới phương thức tại Controller.Điều
này có nghĩa là mỗi lần gọi RenderAction lại là 1 yêu cầu mới (chú ý khi xử lý cache)

// Với những lời gọi trả về lượng lớn Html thì dùng Html.RenderAction hiệu
quả hơn

Controller:

public ActionResultIndex()

returnPartialView("ViewDemo");

public ActionResultIndex()

returnPartialView("ViewDemo", db.BaiViets);

View:

Html.RenderAction

// Có tham số:

@{Html.RenderAction("ActionName ", "ControllerName ", new { id =


item.MaMenu});}

// Không tham số

@{Html.RenderAction("ActionName", "ControllerName");}

Html.Action:

@Html.Action("ActionName ", " ControllerName")

@Html.Action("ActionName ", " ControllerName ", new {id=1 })

Chú ý vấn đề dùng Cache khi gọi Html.{RenderAction,Action}


98
// Khai báo thêm Attribute chỉ định cache

[ChildActionOnly]

public ActionResultIndex()

returnPartialView("ViewDemo");

// Attribute chỉ định các thông tin sẽ không cache qua url

12.5. RenderBody, RenderPage, RenderSection


RenderBody

RenderBody là phương thức dùng gọi các trang kế thừa.Được khai báo ở layout

RenderPage

// RenderPage dùng để gọi nội dung html từ 1 View khác

RenderSection

// Được gọi trong Layout

// Được khai báo trong các trang kế thừa

Sample:

Tại 1 View kế thừa Layout khai báo 1 section:

@section Section1 {

<h1>Section Content</h1>

// Trong Layout gọi Section với cú pháp:

<div>

@RenderSection("Section1",false)

</div>

Hoặc:

99
<div>

@RenderSection("Section1",required:false)

</div>

Các tham số required chỉ định thông báo lỗi hay không khi tìm section

Hoặc có thể kiểm tra như sau:

@if (IsSectionDentitype frameworkined("Section1"))

@RenderSection("Section1",required:false)

else

<h1>Dentitype frameworkault Content</h1>

100
BÀI 13. THẢO LUẬN 3 CÁC TRÌNH ĐIỀU KHIỂN
TRÊN MVC
Lập trình MVC không còn khái niệm kéo thả và xử lý Control như webform,
tuy nhiên VS cũng hỗ trợ mạnh mẽ việc sinh mã máy

Với các thao tác cơ bản như: xem danh sách, sửa, xóa, xem chi tiết, cập nhật ở
phần trên.Có thể dùng VS sinh mã tự động cho cả View và Controller.

Khi hiểu bản chất của code, có thể dùng VS sinh mã máy, và tùy chỉnh mã máy
sau khi được sinh tự động.Đó là sự kết hợp việc lập trình với sự hỗ trợ của môi trường
thiết kế giúp xây dựng ứng dụng được nhanh hơn.

Ở trên ta đã làm quen với việc dùng VS sinh mã máy cho View, dưới đây sẽ
dùng VS tạo mã máy cho cả View và Controller

Bước 1:

Tạo Controller

Model class là lớp Student mà ta cần xem, thêm, sửa, xóa

DataContext class là lớp Entity ánh xạ CSDL

Lựa chọn layout

Nhấn Add, và hãy xem kết quả VS tự động tạo mã cho Sample4Controller và
View tương ứng.

Ta được kết quả là các Controller, View tương tự như phần 6 tạo thủ công code

Hãy xem và so sánh Sample4Controller và Sample3Controller để thấy sức mạnh


của IDE VS sinh mã tự động tốt đến mức nào ?

Một chú ý là với phiên bản Visual Studio 2012 thì các bạn cần xóa bỏ chuỗi kết
nối đặt trong file web.config.Có một lỗi nguyên nhân được xác định là do đặt chuỗi kết
nối sẵn trong webconfig.Chúng tôi đã tìm ra lỗi và đã tìm được giải phải từ Microsoft.
Với phiên bản Visual Studio 2013 đã khắc phục được lỗi này. Khi xóa chuối kết nối,
tạo Controller xong rồi nhập lại chuỗi kết nối.

Kết quả khi chạy Sample4Controller (/sample4) tương tự Sample3.

Và các bạn thấy chỉ vài cấu hình mà ta đã sinh ra được các đoạn mã mà phần 7
chúng ta phải cực nhọc để code.

101
Tuy nhiên mục 7 lại vô cùng quan trọng để các bạn hiểu bản chất mô hình MVC,
mục 8 giúp chúng ta tự động hóa những gì có thể. Đôi khi có những đoạn mã mà mã
máy sinh ra không thể đáp ứng được yêu cầu của ứng dụng

102
BÀI 14. TH 4. SỬ DỤNG ĐIỀU KHIỂN TRONG MVC
Mục tiêu:

- Kết thúc bài thực hành này học viên có thể:


- Tạo một số điều khiển UCC phục vụ cho hệ thống Quản lý cán bộ

Thêm và sử dụng được các thuộc tính, phương thức cho điều khiển UCC

Nội dung:

Bài 1: Tạo một điều khiển Login,có giao diện như sau:

Chương trình minh họa:

Trang Login.ascx

<%@ Control Language="C#" AutoEventWireup="true"


CodeFile="Login.ascx.cs" Inherits="Login" %>

<table runat="server" id="NoiDungLogin" style="border:solid 1px


purple;border- collapse:collapse">

<tr>

<td colspan="2" style="text-align:center; background-


color:purple;color:White">

Đăng nhập

</td>

</tr>

<tr>

<td style="text-align:center;width:40%">User name:</td>

<td>

<asp:TextBox runat="server" ID="txtUserID" Width="99%"></asp:TextBox>

</td>

</tr>

<tr>

<td style="text-align:center; width:40%">Password:</td>

103
<td>

<asp:TextBox runat="server" ID="txtPassword" Width="99%"


TextMode="Password">

</asp:TextBox>

</td>

</tr>

<tr>

<td></td>

<td>

<asp:Button runat="server" ID="cmdCancel" Text="Cancel" />

<asp:Button runat="server" ID="cmdLogin" Text="Login" />

</td>

</tr>

</table>

Bài 2: Tạo điều khiển Login1 có giao diện như bài 1 nhưng thêm thuộc tính
cho

phép đặt độ rộng của điều khiển.

Hướng dẫn: Phần giao diện code như trên, còn phần code C# sẽ thêm thuộc tính
như sau:

Trang Login.ascx.cs

using System;

using System.Web.UI;

public partial class Login : System.Web.UI.UserControl

private string dorong; public string DoRong

104
set

get

dorong = value; NoiDungLogin.Width = dorong;

return dorong;

protected void Page_Load (object sender, EventArgs e)

Tại trang aspx, khi muốn thay đổi độ rộng, chỉ việc thêm thuộc tính DoRong
trong thẻ.

Bài 3: Yêu cầu như bài 2 nhưng có thêm 3 phương thức. Phương thức
CheckAccout() để kiểm tra, nếu User name="asp.net" và password = "123456" thì trả
về true, trái lại trả về false; Phương thức GetUserName trả về giá trị trong ô User name;
phương thức GetPassword trả về giá trị trong ô Password.

Ngoài ra, khi người dùng bấm vào nút "Login" thì sẽ in ra thông báo (trên một
nhãn phía dưới) : "Bạn đã đăng nhập với User name là : … Password là: ….." Hướng
dẫn: Vì bên ngoài không thể truy xuất được vào các thuộc tính của đối tượng con thuộc
UCC, do vậy nếu thực sự muốn truy cập thì ta cần phải xây dựng các phương thức
Public cung cấp các chức năng truy cập (đọc/ ghi) này.

Viết lại trang Login.ascx.cs như sau (Phần giao diện không đổi)

using System;

public partial class Login : System.Web.UI.UserControl

private string dorong; public string DoRong

105
{

set

get

dorong = value; NoiDungLogin.Width = dorong;

return dorong;

public Boolean CheckAccount ()

return (txtUserID.Text == "asp.net" && txtPassword.Text == "123456");

/// Lấy User name trong ô User name public string GetUserName ()

return txtUserID.Text;

/// lấy Password trong ô Password public string GetPassword ()

return txtPassword.Text;

protected void Page_Load (object sender, EventArgs e)

106
}

Trang aspx sử dụng điều khiển này sẽ có dạng:

Nội dung trang C# của trang ASPX

Bài 4: Tạo phần Header và Footer để có thể chèn vào các trang. Giao diện
như sau:

Nội dung của điều khiển Header.ascx (Học viên có thể tùy biến)

Tạo một UCC, có tên Header.ascx như sau:

<%@ Control Language="C#" AutoEventWireup="true"


CodeFile="Header.ascx.cs" Inherits="Header"

%>

<style type="text/css"> A

float:right; width:80px;

text-decoration:none; color:white;

background-color:purple; border-right:1px solid white; text-align:center;

A:Hover

background-color:#ff3300; color:Purple;

</style>

<table border="0px" style="width:790px;border-collapse:collapse">

<tr style="height:80px;background-image:url('body_bg.gif')">

<td style="text-align:center;

vertical-align:middle; font-family:compact; font-size:20pt;

107
font-weight:bold">

HUMAN RESOURCE MANAGEMENT SYSTEM - V2.0

</td>

</tr>

<tr style="height:30pt">

<td style="text-align:right;vertical-align:top;

font-weight:bold;text-decoration:none; color:White">

<a href="LoginDemo.aspx">Login</a>

<a href="Products.aspx">Products</a>

<a href="Downloads.aspx">Download</a>

<a href="Contact.aspx">Contact</a>

<a href="Forums.aspx">Forum</a>

</td>

</tr>

</table>

Bài 5: Tạo Menu cho hệ thống phần mềm quản lý cán bộ.

(Làm lại bài trong tài liệu dùng cho lý thuyết). Nhưng thêm một số hyperlink
khác..

Bài 6: Lắp ghép header, footer và Menu để được trang như sau:

Trang code giao diện của UCC MainMenu.ascx.cs

<%@ Control Language="C#" AutoEventWireup="true"


CodeFile="MainMenu.ascx.cs" Inherits="MainMenu" %>

<style type="text/css">

.A_MainMenu

108
float:none; width:100px;

text-decoration:none; color:purple;

text-align:left;

Giao diện UCC của

MainMenu.ascx

A:Hover

</style>

background- color:silver; color:Purple;

<table border="0px" style="border-collapse:collapse; border:solid 1px


purple;width:150px">

<tr>

<td align="center" style="background-color:Purple; color:White;font-


weight:bold"> Main Menu

</td>

</tr>

<tr>

<td>

<asp:LinkButton Width="100%" CssClass="A_MainMenu" runat="server"


ID="lnkHome" Text="Trang chủ" PostBackUrl="~/HeaderDEMO.aspx">

</asp:LinkButton>

</td>

</tr>

<tr>

<td>

109
<asp:LinkButton Width="100%" CssClass="A_MainMenu"

runat="server" ID="LinkButton1" Text="Giới thiệu"></asp:LinkButton>

</td>

</tr>

<tr>

<td>

<asp:LinkButton Width="100%" CssClass="A_MainMenu"

runat="server" ID="LinkButton8" Text="Liên hệ"></asp:LinkButton>

</td>

</tr>

<tr>

<td>

<asp:LinkButton Width="100%" CssClass="A_MainMenu"

runat="server" ID="LinkButton" Text="Nhập hồ sơ cán


bộ"></asp:LinkButton>

</td>

</tr>

<tr>

<td>

<asp:LinkButton Width="100%" CssClass="A_MainMenu"

runat="server" ID="LinkButton3" Text="Sửa đổi hồ sơ"></asp:LinkButton>

</td>

</tr>

<tr>

<td>

<asp:LinkButton Width="100%" CssClass="A_MainMenu"

110
runat="server" ID="LinkButton4" Text="Tìm kiếm"></asp:LinkButton>

</td>

</tr>

<tr>

<td>

<asp:LinkButton Width="100%" CssClass="A_MainMenu"

runat="server" ID="LinkButton5" Text="Thống kê"></asp:LinkButton>

</td>

</tr>

<tr>

<td>

<asp:LinkButton Width="100%" CssClass="A_MainMenu" runat="server"


ID="LinkButton6" Text="In ấn"></asp:LinkButton>

</td>

</tr>

<tr>

<td align="center" style="background-color:Purple; color:White;font-


weight:bold">

Đăng nhập

</td>

</tr>

<tr>

<td>

User name: <br />

<asp:TextBox runat="server" ID="txtUserName" Width="92%">

</asp:TextBox> <br /> Password: <br />

111
<asp:TextBox runat="server" ID="txtPassword"
Width="92%"></asp:TextBox>

<asp:Button runat="server" ID="cmdLogin" Text="Đăng nhập" />

</td>

</tr>

</table>

112
BÀI 15. SỬ DỤNG LAYOUT
15.1. Giới thiệu Layout trong MVC
Layout là các html Template.Các nội dung không thay đổi của 1 trang web như:
logo, tiêu đề, cuối trang (footer ) được khai báo tại layout.Các trang khác kế thừa nội
dung của layout sẽ chứa các nội dung khai báo trong layout

layout trong Asp.net MVC tương tự như MasterPage trong Asp.net Webform

layout trong mvc được đặt trong thư mục View/Shared

Về mặt code, các thẻ như html, doctype, body là mặc định luôn có trong mọi
trang html, do đó chúng sẽ được khai báo tại layout

Khi tạo 1 ứng dụng MVC mẫu thì Visual Studio có tạo sẵn 1 layout có tên là
_layout trong thưc mục View/Shared

Chúng ta có thể tạo Layout riêng bằng cách chuột phải lên thưc mục Share, chọn
Add Layout Page

Code file _LayoutSample1 như sau:

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width" />

<title>@ViewBag.Title</title>

</head>

<body>

<div>

@RenderBody()

</div>

</body>

</html>

Ta khai báo các thành phần thẻ bắt buộc của tài liệu html như html, body

113
@RenderBody() là nơi đặt nội dung kế thừa của các trang khác

View Index của Sample11Controller sử dụng _LayoutSample1 khai báo như


sau:

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_LayoutSample1.cshtml";

<h2>Đây là trang Index của Sample11 Controller.Dùng


_LayoutSample1</h2>

15.2. Xử lý layout trong MVC


Layout là 1 kiều template hỗ trợ hiển thị những nội dung cố định, và các trang
web khác có thể kế thừa nội dung đó.

Ta hiểu 1 trang web luôn có các thẻ như: html, head, tittle, body …Và ta sẽ tạo
1 layout có sẵn các thẻ này, các trang kế thừa layout không phải khai báo các đoạn mã
chung như thế này

Trong Razor hỗ trợ các đối tượng để xử lý layout như:

RenderBody,RenderPage,RenderSection,LayoutPage

RenderBody

RenderBody là phương thức dùng gọi các trang kế thừa.Được khai báo ở
layout.Giả sử ta có 1 trang layout, và khai báo 1 RenderBody

Nội dung trang kế thừa layout sẽ được hiển thị đúng vào vị trí của RenderBody

RenderPage

// RenderPage dùng để gọi nội dung html từ 1 View khác

Giả sử ta có đoạn mã.cshtml định nghĩa các thẻ Razor (thường là các đoạn mã
được dùng ở nhiều nơi).Và ta sẽ dùng đối tượng RenderPage để gọi các trang này trong
layout

RenderSection

// Được gọi trong Layout.Và cần được khai báo trong các trang kế thừa

114
Ví dụ sử dụng RenderBody,RenderPage, RenderSession

Để cho gọn code và phân loại ví dụ các bạn tạo thư mục LyoutSample và tạo 1
file layout.

Chúng ta đặt tên layout là _Layout.cshtml.Các bạn có thể quan sát 1 file layout
mà Visual Studio sinh mã tự động đó là _SiteLayout.cshtml.Ở đây chúng ta tự tạo mới
1 file layout từ đầu cho các bạn dễ hiểu.

Với mô hình mvc chúng ta có các qui ước đặt file layout ở thư muc Share, tuy
nhiên với Web Page thì chúng ta có thể đặt ở bất kỳ đâu và chỉ cần tham chiếu chính
xác đường dẫn

Mã file _Layout.cshtml được tạo ra như sau:

<!DOCTYPE html>

<html>

<head>

<title>@Page.Title</title>

@RenderSection("head", required: false)

</head>

<body>

@RenderBody()

</body>

</html>

Ở đây layout đã có đủ các thẻ cơ bản của 1 trang html như: doctype, html, head.
body …

Và Visual Studio cũng tạo sẵn cho ta 3 đối tượng là:

@Page.Title

@RenderSection

@RenderBody()

115
Mã trang kế thừa Visual Studio tạo ra như sau:

@{

Page.Title = "Title goes here";

//Layout = "Your Layout Page goes here";

<div>

</div>

Chúng ta sẽ thay đổi 1 vài thông số để sử dụng trong _Layout đã khai báo ở trên
như sau:

@{

Page.Title = "Tiêu Đề WebSite";

Layout = "_Layout.cshtml";

<div>

Hello world.Đây là trang kế thừa _Layout

</div>

Ở đây ta chưa khai báo sử dụng @RenderSection("head", required: false).Do ta


để tham số là false, nên nếu không khai báo thì sẽ không load nội dung
RenderSection.Nếu để là true (mặc định) mà không khai báo thì sẽ báo lỗi là không tìm
thấy RenderSection

Giả sử ta khai báo sử dụng RenderSection như sau:

@{

Page.Title = "Tiêu Đề WebSite";

Layout = "_Layout.cshtml";

@section head {

116
<meta charset="utf-8" />

<div>

Hello world.Đây là trang kế thừa _Layout

</div>

Ở đây ta khai báo với từ khóa @section head head là tên của RenderSection
định nghĩa trong layout

section heade khai báo các thẻ tiêu đề cho website như thẻ meta, description …

Và chúng ta có thể khai báo bất kỳ 1 thẻ nào trong section

Ví dụ dưới đây chúng ta sẽ sử dụng thêm đối tượng RenderPage

Tạo mới 1 file _footer.cshtml trong thư mục LayoutSample (các bạn có thể tạo
ở thư mục bất kỳ nhưng cần chú ý khai báo tham chiếu đúng tời thư mục chứa file trong
lời gọi RenderPage)

Soạn mã _footer.cshtml như sau:

<div id="footer">

<hr />

<p>

Tiêu đề cuối website

</p>

</div>

Gọi _footer.cshtml trong _Layout như sau:

<!DOCTYPE html>

<html>

<head>

<title>@Page.Title</title>

@RenderSection("head", required: false)

</head>
117
<body>

@RenderBody()

@RenderPage("_footer.cshtml")

</body>

</html>

Chúng ta có thể gọi _footer.cshtml trong file bất kỳ

Việc sử dụng các đối tượng Layout là rất quan trọng trong các ứng dụng Asp.net
WebPage cũng như trong ứng dụng Asp.net MVC.Chúng giúp chúng ta code website
không bị trùng lặp, mã rõ ràng và tất nhiên và khả năng kế thừa nhiều nơi trong Project
hay nhiều Project khác nhau.

15.3. Khái niệm attribute


Như đã học phần trước về xử lý dữ liệu với bảng Student, các trường như là
Name ta cần không được để trống, trường Phone phải nhập số ta có khai báo lớp Student
như sau:

public class Student

public int ID { get; set; }

[Required(ErrorMessage = "không được rỗng")]

public string Name { get; set; }

[RegularExpression("[0-9]{1,5}", ErrorMessage = "Bạn phải nhập số")]

public intPhone { get; set; }

// Dưới đây là các Attribute thường dùng

[Key] Chỉ định trường Primary.


ENTITYPE FRAMEWORK tự động gán trường có hậu
tố ID làm trường Primary nếu Attribute không được khởi
tạo
Trường Key có kiểu int sẽ tự động là kiểu tự động tăng

118
[ScaffoldColumn(false)] Ẩn hiện thuộc tính trong chế độ Editor (Create, Edit)

[HiddenInput(DisplayValue = Ẩn hiện thuộc tính trong chế độ xem (index)


false)]
Các thuộc tính trên chỉ có ý nghĩa khi
dùng @Html.EditorForModel() tự động generate View

public int? Level { get; set; } cho phép null

[Display(Name = "Tên")] Đặt tên thuộc tính hiển thị

[Required(ErrorMessage = "không khai báo trường không được để trống


được rỗng")]
[Required]

[DataType(DataType.Password)] Định dạng trường kiểu Password

[DisplayFormat(DataFormatString Formart tự động kiểu Date sang string


= "{0:dd/MM/yyyy}",
ApplyFormatInEditMode = true)]

[MaxLength] Số ký tự tối ta tương ứng với kiểu dữ liệu

[Column(TypeName = "ntext")] Kiểu dữ liệu là ntext dưới CSDL

[DataType(DataType.MultilineTex hiển thị textArea


t)]

[UIHint("CkEditor")] Hiển thị bằng Template có tên là CkEditor

[RegularExpression("[0-
9]{1,5}",ErrorMessage = "Tuổi
phải là chữ số")]

[a-z0-9_] điều kiện như trên và ít nhất 1 ký tự


[a-z0-9_] điều kiện như trên và ít nhất 0 ký tự
[a-z0-9_]{4,20} điều kiện như trên và ít nhất 4 ký tự và nhiều nhất là 20
ký tự

15.4. Sử dụng CkEditor Template


Ta tạo lớn News (Tin tức ) có nhiều trường để mô tả ý nghĩa của các Attribute

Do không tạo xứ lý dữ liệu lưu xuống CSDL nên ta tạo file News.cs trong thư
mục ViewModel (Tạo mới thư mục ViewModel)

Code lớp News.cs như sau:

119
public class News

public int ID { get; set; }

[Display(Name = "Tiêu đề Tin")]

[Required(ErrorMessage = "Tiêu đề không được trống")]

public stringTitle { get; set; }

[Display(Name = "Mô tả")]

[Required(ErrorMessage = "Chưa nhập mô tả nội dung")]

// hiển thị mô tả bằng textArea

[DataType(DataType.MultilineText)]

public stringDiscription { get; set; }

[Display(Name = "Nội dung")]

[Required(ErrorMessage = "Chưa nhập nội dung")]

// hiển thị mô tả dùng thư viện CkEditor

[UIHint("CkEditor")]

public stringContent { get; set; }

// Phần lớn là các attribute mvc cung cấp sẵn.Chú ý thuộc


tính [UIHint("CkEditor")] mvc không cung cấp sẵn template CkEditor.

// Việc cấu hình và sử dụng CkEditor các bạn có thể xem tại website CkEditor
hoặc xem hướng dẫn cụ thể của chúng tôi trong các tài liệu về lập trình ứng dụng
MVC.Ở đây chúng tôi hướng dẫn sử dụng CkEditor với chức năng tạo template trong
MVC.Mỗi trường khai báo Attribute [UIHint("CkEditor")] khi Create, Edit sẽ dùng
CkEditor để soạn thảo nội dung

// Để tạo template CkEditor ta làm như sau:

Download thư viện CkEditor tại website: http://ckeditor.com/

Copy thư viện vào thư mục Scripts

120
Tạo thư mục EditorTemplates trong thư mục Shared

Tạo file CkEditor.cshtml trong thưc mục View/Shared/EditorTemmplates

Mã file CkEditor.cshtml như sau:

<script src="../Scripts/ckeditor/ckeditor.js"></script>

<textarea class="ckeditor" name="editor1"></textarea>

Ta xây dựng code sử dụng CkEditor như sau:

Controller:

public ActionResultIndex()

returnView();

View:

Mã VS tự động sinh như sau:

@model SampleMvc.ViewModel.News

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

@using (Html.BeginForm())

@Html.ValidationSummary(true)

<fieldset>

<legend>News</legend>

<div class="editor-label">

121
@Html.LabelFor(model => model.Title)

</div>

<div class="editor-field">

@Html.EditorFor(model => model.Title)

@Html.ValidationMessagentitype frameworkor(model => model.Title)

</div>

<div class="editor-label">

@Html.LabelFor(model => model.Discription)

</div>

<div class="editor-field">

@Html.EditorFor(model => model.Discription)

@Html.ValidationMessagentitype frameworkor(model =>


model.Discription)

</div>

<div class="editor-label">

@Html.LabelFor(model => model.Content)

</div>

<div class="editor-field">

@Html.EditorFor(model => model.Content)

@Html.ValidationMessagentitype frameworkor(model =>


model.Content)

</div>

<p>

<input type="submit" value="Create" />

</p>

</fieldset>

122
}

@section Scripts {

@Scripts.Render("~/bundles/jqueryval")

Chú ý: Để sử dụng validate cần khai báo 2 thư viện javascript sau:

<script src="~/Scripts/jquery.validate.js"></script>

<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

// 2 thư viện này có sẵn trong thư mục Script của project

// ở đây dùng tính năng bundled (MVC 4 – MVC 5 ) để tạo ra file javascript ảo
jQueryval. Các bạn có thể khai báo trức tiếp 2 file trên (xem thêm phần xử dụng bundled
)

// ta thấy các Attribute đã có tác dụng, các trường hiển thị tên tiếng việt,

Trường Description(mô tả) được hiển thị bằng 1 textArea, trường Content (nội
dung) được hiển thị bằng thư viện CkEditor

Các trường Title,Description không được để trống.Khi chưa nhập dữ liệu nếu
nhấn create thì sẽ báo lỗi

Ở đây ta không xây dựng các chức năng xử lý nội dung khi nhập liệu đúng.Việc
xử lý nội dung như các phần 6 và phần 7 về CRUD dữ liệu

123
BÀI 16. TH 5. XÂY DỰNG TRANG MASTERPAGE
Sử dụng cơ sở dữ liệu đã tạo được trong bài tập 2 để thực hiện các công việc
sau:

Bài 1: Thực hiện tạo giao diện cho trang quản trị tin tức

Bài 2: Thực hiện tạo giao diện cho trang quản trị website bán hang

Bài 3: Thực hiện tạo giao diện trang chủ cho website tin tức

Trang chủ

124
Trang chi tiết

Bài 4: Thực hiện tạo giao diện trang chủ cho website bán hàng

125
BÀI 17. THẢO LUẬN 4 XÂY DỰNG GIAO DIỆN
WEBSITE SỬ DỤNG TEMPLATE
17.1 Thiết kế giao diện web
Là công đoạn quan trọng nhất quyết định sức hấp dẫn của doanh nghiệp khi
người dùng ghé thăm. Thiết kế giao diện web không những cần phải ấn tượng, độc
đáo mà còn chứa nội dung dễ nhìn, thân thiện với người xem. Trên thực tế, việc chọn
một phong cách thiết kế có đúng ý muốn của bạn hay không còn phụ thuộc vào các yếu
tố như ngân sách, thời gian, khả năng của người thiết kế web,...

Nói về cách thiết kế giao diện web, ta có thể chia làm ba loại: thiết kế theo
templates (modify from template), tự thiết kế theo yêu cầu (unique design) và kết hợp
sử dụng hai phương pháp (average design). Để hiểu rõ hơn sự khác biệt giữa những
phương thức này, cũng như biết điểm mạnh/điểm yếu của từng cách là gì, xin mời Quý
khách tham khảo bài viết dưới đây để chọn cho mình một phương án thiết kế phù hợp
nhất.

Template là gì? Template có tác dụng gì trong thiết kế giao diện web?

Trước khi phân tích những khía cạnh khác nhau của thiết kế giao diện web sử
dụng template có sẵn, ta cần hiểu rõ template là gì. Template, còn được gọi là mẫu chủ
đề hoặc mẫu đồ họa, được định nghĩa là một mẫu trang thô sơ, tại đó có sẵn các bố cục
hình ảnh, nội dung, hiệu ứng sẵn sàng cho việc xây dựng một trang web. Thông thường
1 template được sử dụng cho nhiều trang web khác nhau và 1 trang web cũng có thể áp
dụng được nhiều kiểu template khác nhau.

Template là thành phần không thể thiếu và là yếu tố đầu tiên cần chuẩn bị khi
bạn đang có kế hoạch xây dựng website riêng cho doanh nghiệp. Các mẫu template
hiện nay có hàng ngàn sự lựa chọn rất phong phú và ngày càng được nâng cấp với nhiều
định dạng trang trí đặc sắc nhằm đem đến những trải nghiệm tốt hơn cho người dùng.
Nhiều mẫu cũng được trang bị các plug-in rất thú vị.

Thiết kế giao diện web có nên sử dụng template (modify from template) hay
không?

Chúng tôi không khuyên bạn phải sử dụng phương thức nào để tạo nên website
của mình. Thay vào đó, đội ngũ Markdao Vietnam xin phân tích những lợi ích của việc
sử dụng template, cũng như những mặt hạn chế để bạn có thể cùng chúng tôi thiết kế
giao diện web tốt hơn.

17.2. Modify from template đem lại những lợi ích gì?
TIẾT KIỆM THỜI GIAN:

Thật không thể bàn cãi về lợi ích này khi sử dụng template có sẵn cho thiết kế
web. Một nhà sáng tạo trước khi công khai sản phẩm template của mình, họ đã nghiên
cứu rất kĩ cách bố trí layout, cách sắp xếp hình ảnh, bài viết, thông tin sao cho có tính
126
thẩm mỹ cao. Đồng thời bố cục phải làm sao cho người xem tiếp nhận thông tin tốt
nhất. Chính vì vậy, chúng ta không cần phải tiêu tốn quá nhiều thời gian cho việc suy
nghĩ bố cục hợp lí. Có hàng ngàn sự lựa chọn sẵn sàng trên website và bạn chỉ cần cùng
chúng tôi chọn ra template bạn thích nhất.

Vấn đề thường gặp là khách hàng luôn có xu hướng cần website càng sớm càng
tốt, do đó việc dùng phương thức modify from template cho phép đội ngũ thiết kế tiết
kiệm thời gian hơn, từ đó giao website nhanh chóng hơn, và bạn có thể bắt đầu việc
kinh doanh của mình sớm hơn.

TIẾT KIỆM CHI PHÍ:

Vì tính chất “có sẵn” cho nên việc thiết kế giao diện web không cần phải tiêu
tốn quá nhiều thời gian suy nghĩ. Và vì tiết kiệm được thời gian cho nên bạn sẽ giảm
thiểu được chi phí đầu tư. “Time is money” là có thật! Hơn nữa, hiện nay đã có rất
nhiều mẫu thích hợp với sở thích của bạn, và chúng được thiết kế bởi những bộ phận
được tạo ra chỉ để “chuyên trị” giai đoạn này. Do đó nó thường được bán với giá rẻ hơn
nhiều.

DỄ DÀNG UPDATE:

Do các mẫu trang web có sẵn được thực hiện bởi một nhà sản xuất, cho nên khi
mua template đó, chúng ta sẽ nhận được những cập nhật mới trong tương lai. Chỉ cần
bấm nút “UPDATE” là ta có được một phiên bản tốt hơn. Điều này sẽ giúp duy trì độ
ổn định của trang web, đồng thời giảm thiểu các lỗi xảy ra trên đường.

Một ích lợi khác của việc sử dụng template có sẵn cho thiết kế giao diện web
là dễ dàng cập nhật xu hướng. Giữa thị trường đầy cạnh tranh, câu hỏi: gần đây mọi
người thích gì? Người dùng bị thu hút bởi điều gì?...là những gì bạn cần quan tâm nhất
nhằm đưa website của mình đến gần hơn với khách hàng tiềm năng. Lúc này, các
template hot nhất hiện nay luôn sẵn sàng để bạn áp dụng cho website của mình. Tuy
nhiên, xu hướng nào rồi cũng sẽ phai tàn để nhường bước cho những thứ mới mẻ hơn
lên ngôi. Đừng lo lắng! Với sự tiên lợi khi sử dụng template có sẵn, bạn có thể dễ dàng
đổi giao diện mà không phải tốn quá nhiều thời gian để bắt đầu trở lại thiết kế layout.

ĐỘ CHÍNH XÁC CAO:

Để thiết kế giao diện web chuẩn SEO, bạn cần nhớ rằng không chỉ chú trọng
vào “mặt tiền” của website mà còn phải sành sỏi về những kĩ thuật “nằm sau” trang
web, điển hình là code. So với việc tự tạo ra các dòng code thì sử dụng template với
mẫu code có sẵn sẽ giúp bạn hiệu chỉnh một cách chính xác hơn. Hiện nay đã có khá
nhiều template hỗ trợ thiết kế web chuẩn SEO, cho nên bạn không cần phải viết code
quá nhiều, trừ khi bạn cần chỉnh sửa chuyên sâu về vấn đề nào đó. Viết càng ít, lỗi sai
càng hiếm, từ đó trang web của bạn sẽ được tối ưu hơn.

127
BÀI 18. BIẾN TRẠNG THÁI TRONG MVC
18.1. Cookie
Cookie được lưu cả ở Client và Server nên có thể tương tác với đối tượng này
cả bằng mã.net tại server hoặc mã script tại Client

Cookie có thời gian sống cụ thể,và có thể được xóa bằng các chương trình phía
Client hoặc gửi lệnh xóa Cookie lên Server

Một ứng dụng nhỏ của cookies đó là lưu thông tin đăng nhập người dùng vào
cookies

Mô tả cách sử dụng 1 Cookie:

Tại 1 Controller,Action nào đó ta tạo 1 Cookie,giá trị của Cookie có thể lấy
dưới View (người dùng nhập liệu),dưới dataBase hoặc khởi tạo sẵn 1 đối tượng nào đó

Trả Cookie này về browser, có thể kiểm tra giá trị Cookie được lưu trữ dưới
Browser bằng các tool view code

Tại các Action,View của Controller bất kỳ có thể đọc nội dung Cookie được
lưu dưới Browser

// Action khởi tạo và gửi Cookie về Browser:

// GET: /Sample13/

public ActionResultIndex()

// Khởi tạo 1 Cookie

HttpCookie ck = new HttpCookie("Cookie1") { Value = "This is


Cookies 1", Expires = DateTime.Now.AddDays(10) };

//Gửi Cookie về Browser (Ghi Cookie vào trình duyệt dưới Client)

Response.Cookies.Add(ck);

returnView();

public ActionResultAction1()

128
returnView();
}
// Trường hợp Cookies chưa được tạo hay đã hết hạn thì lấy giá trị là null
Đọc Cookies tại View:
// Tại View bất kỳ có thể gọi Cookie như sau:
@Request.Cookies["Cookie1"].Value
Giả sử ta tạo View Action1.cshtml tương ứng với Action1.Mã file
Action1.cshtml như sau:
@{
ViewBag.Title = "Action1";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Action1</h1>
<h2>
@Request.Cookies["Cookie1"].Value
</h2>
(Ví dụ trên khi gọi tới Action Index của Sampl13Controller thì tạo Cookies có
tên là Cookies1, tại View của Action1 hiển thị nội dung Cookies.
Chạy ứng dụng: Gọi Action Index của Sample13Controller để tạo Cookies được
kết quả:
Gọi tiếp Action1 của Sample13Controller để hiển thị nội dung Cookies được
kết quả

Đọc Cookie tại Controller :

Ở trên ta đã đọc Cookies trên View, việc đọc Cookies tại Controller cũng tương
tự.Tại Controller bất kỳ muốn đọc giá trị Cookies ta làm như sau:

public ActionResultAction3()

stringstrCookies;

if(Request.Cookies["Cookie1"] == null)

129
{

strCookies = "Bạn chưa tạo Cookies";

else

strCookies = Request.Cookies["Cookie1"].Value;

returnView();

18.2. Session
Section là đối tượng lưu trữ thông tin 1 phiên làm việc của người dùng

Section được lưu trữ tại server. Khi người dùng tắt trình duyệt thì Session tự
động mất

Section có thời gian sống cụ thể như Cookie.Tuy nhiên muốn xóa Section chỉ
có thể gửi lệnh lên Server (không xóa được bằng các trình dọn dẹp trên hệ thống Client)

Tương tự như Cookies, khi chưa được khởi tạo giá trị thì biến session có giá trị
là null

Một điểm quan trọng mà session khác cookies đó là session có thể lưu trữ các
kiểu dữ liệu tham chiếu như List<T>,array …

Một ứng dụng nhỏ của session đó là việc xây dựng giỏ hàng với các web bán
hàng

Ví dụ dùng session:

Controller:

public ActionResultIndex()
{
Session["Session"] = "Session1";
returnView();
130
}
public ActionResultAction1()
{
returnView();
}
View Index:
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>
@Html.ActionLink("Tới Action1","Action1")
View Action1:
@{
ViewBag.Title = "Action1";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Action1</h2>
<h2>@Session["Session"].ToString()</h2>
Chạy ứng dụng và gọi Action Index của Sample14Controller để tạo session
được kết

Sau đó gọi tới Action1 của Sample14Controller để hiển thị thông tin session

Tương tự Cookies có thể gọi session trong Controller như sau:

// tại trang bất kỳ, hoặc Action của Controller bất kỳ ta có thể sử dụng biến
Sesstion ở trên

public ActionResultAction2()

stringstrSession = Session["Session1"].ToString();
131
returnView();

132
BÀI 19. BẢO MẬT – PHÂN QUYỀN TRONG ỨNG
DỤNG MVC
19.1. Tạo Controller kiểm tra đăng nhập
Để đơn giản ví dụ ta tạo Controller đăng nhập, không kiểm tra thông tin khớp
lệnh đăng nhập so với thông tin dưới CSDL mà chỉ lưu thông tin đăng nhập vào cookies

Tạo ViewModel hỗ trợ tạo View đăng nhập.Tạo file LogOnVM.cs trong thư
mục ViewModel, code file LogOnVM.cs như sau:

public class LogOnVM

public stringUserName { get; set; }

[DataType(DataType.Password)]

public stringPassword { get; set; }

// Ở đây ta dùng Attribute để MVC tự động sinh ra thẻ input nhập password (ẩn
nội dung)

Controller

tạo Action LogOn như sau:

public ActionResultIndex()

returnView();

[HttpGet]

public ActionResultLogOn()

returnView();

}
133
[HttpPost]
public ActionResultLogOn(LogOnVM model)
{
if(ModelState.IsValid)
{
// lưu thông tin đăng nhập vào cookies
FormsAuthentication.SetAuthCookie(model.UserName, true);
returnRedirectToAction("Index");
}
returnView(model);
}
Khi đăng nhập thành công thì sẽ lưu thông tin đăng nhập (tên đăng nhập) vào
cookies, và điều hướng tới trang Index của Sample15Controller

View Index có nội dung như sau

{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Trang Sample15 Index </h2>
<h2>Bạn đã đăng nhập hệ thống</h2>
@Html.ActionLink("Đăng Xuất","LogOff")

Tùy chỉnh web.config

Với các phiên bản Visual Studio 12 và trước đó thì mặc định đã khai báo module
FormsAuthentication trong web.config, với Visual Studio 2013 thì bạn cần thay đổi 1
chút. Mặc định cấu hình thẻ web.server như sau:

<system.webServer>

<modules>

<remove name="FormsAuthentication" />

134
</modules>

</system.webServer>

Chúng ta đổi thành:

<system.webServer>

<modules>

<remove name="FormsAuthenticationModule" />

</modules>

</system.webServer>

// Gõ tên đăng nhập và mật khẩu bất kỳ và nhấn vào link đăng nhập ta được kết
quả như hình sau:

// Khi người dùng nhấn vào link đăng xuất thì gọi tới Action LogOff của. Action
này đơn giản là xóa thông tin đăng nhập khỏi Cookies, mã Action LogOff như sau:

public ActionResultLogOff()

FormsAuthentication.SignOut();

returnRedirectToAction("Index");

135
// Khi nhấn vào Link đăng xuất thì vẫn điều hướng người dùng ở lại trang Index.
Để phân biệt nội dung khi người dùng đăng nhập và không đăng nhập vào hệ thống ta
code lại View Index như sau:

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Trang Sample15 Index </h2>

@{

if(Request.IsAuthenticated)

<h2>Bạn đã đăng nhập hệ thống</h2>

@Html.ActionLink("Đăng Xuất", "LogOff")

else

<h2>Bạn chưa đăng nhập hệ thống </h2>

@Html.ActionLink("Đăng Nhập", "LogOn")

19.2. Bảo vệ Action – Controller tránh truy xuất


Với ví dụ phần trên ta có thể ẩn hiện nội dung khi đăng nhập – chưa đăng nhập
hệ thống. Tuy nhiên 1 vấn đề nữa đó là 1 vài Action cần yêu cầu đăng nhập vào mới có
thể truy xuất.

MVC cung cấp attribute hỗ trợ làm điều này. Với Action được bảo vệ khi chưa
đăng nhập, nếu gõ trực tiếp tại thanh địa chỉ trình duyệt thì MVC sẽ báo lỗi, hoặc ta có
thể cấu hình để điều hướng tới trang đăng nhập (cấu hình này được khai báo trong tệp
web.config)

136
Giả sử Action Index dưới đây giới hạn truy cập. Nếu chưa đăng nhập mà truy
vấn tới Action Index sẽ báo lỗi.

Code Sample15Controller như sau:

[Authorize]

public ActionResultIndex()

returnView();

Hoặc ta có thể lọc bảo mật cho cả Controller khi khai báo Attribute Authorize
tại Controller như sau:

[Authorize]

public class Sample16Controller: Controller

public ActionResultIndex()

returnView();

View Index.cshtml

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<h2>Đây là View Index của Sample16Controller</h2>

137
Chạy ứng dụng và gọi tới Action Idex (/sample16)

Do chưa đăng nhập nên mvc sẽ điều hướng tới trang LogOn (mặc định là
LogOnController ).Việc chỉ định điều hướng tới Action của Controller bất kỳ được khai
báo trong file web.config. Ở ví dụ trước (Sample15Controller) ta đã xây dựng Action
LogOn.Ta sẽ điều hướng tới Action này khi người dùng truy cập Action Index
(Sample16Controller) mà chưa đăng nhập.

Chạy ứng dụng và truy vấn tới Action Index của Sample16Controller
(/sample16).Do chưa đăng nhập nên MVC tự động điều hướng tới Action
LogOn của Sample15Controller

19.3. Phân quyền truy cập


Một yêu cầu rất hay dùng đó là phân quyền hiển thị hoặc phân quyền truy cập
vào 1 tính năng nào đó của ứng dụng.Giả sử chỉ có các User có quyền admin mới có
thể chỉnh sửa web, quyền member (thành viến) thì chỉ có thể làm 1 vài tác vụ liên quan
tới tài khoản cả nhân như đổi mật khẩu, hình đại diện …

Phân quyền trên View:

Để phân quyền trên view, mỗi khi đăng nhập vào hệ thống thì lưu quyền vào
cookie.Dưới View kiểm tra quyền tương ứng với nội dung hiển thị

Ta thêm code vào Action LogOn của Sample15Controller như sau:

public ActionResultLogOn(LogOnVM model)

if(ModelState.IsValid)

// lưu quyền vào cookies

Response.Cookies.Add(new HttpCookie("Role") { Value


= "Admin", Expires = DateTime.Now.AddDays(30) });

// lưu thông tin đăng nhập vào cookies

FormsAuthentication.SetAuthCookie(model.UserName, true);

returnRedirectToAction("Index");

returnView(model);
138
}

Ở đây ta gán quyền tĩnh. Thường thì lấy quyền được lưu dưới CSDL

Tại View Index ta có thể kiểm tra quyền đăng nhập và hiển thị nội dung tương
ứng như sau (thực ra là đọc nội dung Cookies có tên là Role rồi xử lý phân quyền )

View Index (Sample15Controller) thêm code như sau:

@* Nội dung có xử lý phân quyền *@

@{

if(Request.IsAuthenticated)

<h2>Bạn đã đăng nhập hệ thống</h2>

@Html.ActionLink("Đăng Xuất", "LogOff")

if(Request.Cookies["Role"] != null&& Request.Cookies["Role"].Value


== "Admin")

<h1>Bạn đăng nhập với quyền Admin</h1>

else

<h1>Bạn đăng nhập với quyền không phải Admin</h1>

else

<h2>Bạn chưa đăng nhập hệ thống </h2>

@Html.ActionLink("Đăng Nhập", "LogOn")

139
}

Phân quyền trên Controller

ta có thể khai báo phân quyền truy vấn tới 1 Action hoặc cả Controller với
Attribute như ví dụ sau:

[Authorize(Roles = "admin")]

public ActionResultIndex()

returnView();

Ở đây ta điều quan trọng là ta cần lấy quyền thông qua Provider của
MemberShip.Được khai báo mặc định trong file web.config mà Microsoft cung cấp
sẵn. Khi tạp template MVC, VS tự động sinh mã AccountController đăng nhập và lấy
quyền dưới CSDL được lưu vào CSDL với chuỗi kết nối có tên là Dentitype
frameworkaultConnectionString trong file web.config (VS sẽ tự động tạo CSDL. Các
bạn có thể tạo tĩnh các User, và quyền hạn thông qua công cụ Administration Tool tích
hợp sẵn của VS (Project/Asp.net Configuration )

Đồng thời MVC cũng cung cấp các lớp để có thể quản lý người dùng và quyền
hạn.

Một yêu cầu khi phát triển ứng dụng thực tế đó là có thể tạo các bảng dữ liệu
chứa thông tin đăng nhập, quyền hạn tích hợp vào CSDL chứa các thông tin khác của
ứng dụng. Đồng thời vần xử lý được phân quyền. Để làm điều này ta có 1 giải pháp đó
là tự tạo 1 Provider riêng, kế thừa Provider của mvc, sau đó khai báo Provider trong
file web.config

19.4. Tạo Provider riêng để phân quyền truy cập Action


Xây dựng Provider

tạo 1 lớp kế thừa lớp RoleProvider có tên là MyRoleProvider như sau:

public class MyRoleProvider:RoleProvider

public override voidAddUsersToRoles(string[] usernames, string[]


roleNames)

140
throw new NotImplementedException();

public override stringApplicationName

get

throw new NotImplementedException();

set

throw new NotImplementedException();

public override voidCreateRole(string roleName)

throw new NotImplementedException();

public override boolDeleteRole(string roleName, boolthrowOnPopulated


Role)

throw new NotImplementedException();

public override string[]


FindUsersInRole(string roleName, stringusernameToMatch)

throw new NotImplementedException();

141
}

public override string[] GetAllRoles()

throw new NotImplementedException();

public override string[] GetRolesForUser(string username)

throw new NotImplementedException();

public override string[] GetUsersInRole(string roleName)

throw new NotImplementedException();

public override boolIsUserInRole(string username, stringroleName)

throw new NotImplementedException();

public override voidRemoveUsersFromRoles(string[] usernames, string[]


roleNames)

throw new NotImplementedException();

public override boolRoleExists(string roleName)

throw new NotImplementedException();

142
}

RoleProvider là 1 abstract class nên ta cần khai báo ghi đè các phương thức.VS
hỗ trợ khai báo code hiện thức các phương thức

Ở đây ta quan tâm tới phương thức GetRolentitype frameworkorUser

public override string[] GetRolesForUser(string username)

throw new NotImplementedException();

Phương thức trả về mảng chuỗi các quyền của 1 user.Thông thường ta lấy dữ
liệu dưới CSDL rồi trả về danh sách quyền hạn tương ứng với user tại đây.Ở ví dụ này
ta lưu quyền hạn tĩnh như sau:

public override string[] GetRolesForUser(string username)

return new string[] { "admin", "user"};

Việc lấy thông tin dưới CSDL giả sử được mô ta như sau:

AppEntity db = new AppEntity();

var data = db.Users.Where(x => x.UserName == username).ToList();

return new string[] { data[0].Role };

Khai báo Provider trong web.config

Thêm đoạn code:

<roleManager enabled="true" dentitype


frameworkaultProvider="MyRoleProvider">

<providers>

<clear />

<add name="MyRoleProvider" type="Mvc4App.Models.MyRoleProvide


r" />

143
</providers>

</roleManager>

như hình sau:

đồng thời cần tắt đăng ký MemberShip mặc định

<appSettings>

<add key="enableSimpleMembership" value="false" />

</appSettings>

Chú ý: khai báo type="Mvc4App.Models.MyRoleProvider" chính là tên đầy


đủ lớp MyRoleProvider (gồm cả namespace của nó )

khi này trong ứng dụng ta có thể khai báo phân quyền trên Action như sau:

[Authorize(Roles = "admin")]

public ActionResultIndex()

returnView();

Với ứng dụng thực tế cần code lại việc trả về quyền tương ứng với tên đăng
nhập tại phương thức GetRolentitype frameworkorUser của MyRoleProvider.Việc lưu
quyền vào cookie tương tự phần 3

Các bạn có thể xem mã nguồn trong các file: Model/MyRoleProvider.cs và


web.config

Chúng ta sẽ gặp lại các kỹ thuật này trong việc xây dựng các ứng dụng bán
hàng, tin tức

144
BÀI 20. TH 6 SỬ DỤNG BIẾN TRẠNG THÁI TRONG
MVC

Bài tập:

Thiết kế trang giỏ hàng cho phép người dùng thêm sản phẩm, thanh toán theo
tổng tiền sản phẩm.

Hướng dẫn

Bước 1: Tạo class CartItem.cs như sau:


public class CartItem
{
public string Hinh { get; set; }
public int SanPhamID { get; set; }
public string TenSanPham { get; set; }
public int DonGia { get; set; }
public int SoLuong { get; set; }
public int ThanhTien
{
get
{
return SoLuong * DonGia;
}
}

Bước 2: Tạo GioHangController và sửa nội dung trong action Index như sau:
public ActionResult Index()
{
List<CartItem> giohang = Session["giohang"] as List<CartItem>;
return View(giohang);

Nội dung trong action Index đơn giản là gán Session có key là giohang qua
biến giohangrồi truyền qua view.
Bước 3: Tạo view Index.cshtml của GioHangController, view có 1 table chứa danh sách
các CartItem nằm trong biến giohang được lấy từ action Index.
@model List<CartItem>
@{
ViewBag.Title = "Giỏ hàng của bạn";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@ViewBag.Title</h2>

145
@if (Model == null || Model.Count == 0)
{
<p class="text-info text-center">
Giỏ hàng của bạn rỗng!
</p>
}
else
{
<div class="row">
<div class="col-sm-12">
<div class="table-responsive">
<table class="table table-bordered">
<tr>
<th>Hình</th>
<th>Tên sản phẩm</th>
<th>Số lượng</th>
<th>Đơn giá</th>
<th>Thành tiền</th>
<th></th>
</tr>
@foreach (CartItem item in Model)
{
<tr>
<td class="text-
center"><imgsrc="~/Content/Photos/SanPham/@item.Hinh" width="70" height="60" /> </td>
<td><a target="_blank" href="@Url.Action("ChiTiet", "SanPham", new { id =
item.SanPhamID })"> @item.TenSanPham </a> </td>
<td>
<form action="@Url.Action("SuaSoLuong")"method="get">
<input type="hidden" name="SanPhamID"value="@item.SanPhamID" />
<input type="number" min="1" step="1"name="soluongmoi" value="@item.SoLuon
g" />
<button type="submit" class="btn btn-primary btn-sm"> Cập nhật </button>
</form>
</td>
<td> @item.DonGia.ToString("#,##0").Replace(',', '.') VNĐ </td>
<td> @item.ThanhTien.ToString("#,##0").Replace(',', '.') VNĐ </td>

<td> <a href="@Url.Action("XoaKhoiGio",new { SanPhamID =


item.SanPhamID})" onclick="return confirm('Bạn có chắc muốn xóa sản phẩm này?');" class="btn btn-
danger btn-sm">Xóa</a> </td>
</tr>
}
<tr>
<td></td>
<td class="text-right">Tổng số lượng:</td>
<td> @Model.Sum(m => m.SoLuong) </td>
<td class="text-right">Tổng thành tiền:</td>
<td>@Model.Sum(m => m.ThanhTien).ToString("#,##0").Replace(',', '.') VNĐ </td>
</tr>
</table>
</div>

</div>

</div>

146
BÀI 21. JAVASCRIPT JQUERY CSS
21.1. Sử dụng CSS định dạng Layout
Khi tạo ứng dụng mẫu MVC, Visual Studio đã tạo sẵn 1 file css
(Content/site.css) dùng để thiết kế định dạng CSS tại file này.Đồng thời VS cũng định
dạng CSS sẵn 1 vài đối tượng layout, control.Nếu bạn có kiến thức về CSS có thể xóa
bỏ các định dạng này và tự tạo định dạng cho riêng mình.

Ví dụ dưới đây khai báo CSS luôn trong View (các bạn có thể khai báo trong
file site.css)

Việc bố trí mã nguồn CSS sao cho tối ưu, chúng tôi sẽ hướng dẫn trong các giáo
trình về lập trình ứng dụng MVC thực tế trên cơ sở xây dựng các web tin tức, bán hàng.

Xóa các mã Visual Studio tự động khai báo trong file Content/Site.css

Ta sẽ định dạng lại layout (_Layout.cshtml)

Chỉnh lại nội dung layout như sau:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>@ViewBag.Title My ASP.NET Application</title>

<link hrentitype framework="~/Content/Site.css" rel="stylesheet" />

</head>

<body>

<header>

<div>header website</div>

<div class="float-right" id="LogOn">

<a hrentitype framework="#">Đăng Nhập</a>

<a hrentitype framework="#">Thoát</a>

147
</div>

<nav class="mainMenu clear-both">

<a hrentitype framework="#">Trang Chủ</a>

<a hrentitype framework="#">Giới Thiệu</a>

</nav>

</header>

<div class="body">

<section>

@RenderBody()

</section>

</div>

<footer>

footer website

</footer>

@RenderSection("scripts", required: false)

</body>

</html>

Chúng ta chú ý tới khai báo tham chiếu tới file CSS:

<link hrentitype framework="~/Content/Site.css" rel="stylesheet" />

Trong mã Layout chúng ta có sử dụng 1 số thẻ html5 để định nghĩa nội dung.

Ta khai báo mã CSS trong file Site.css để định nghĩa các lớp css dùng trong
layout như sau:

body{margin:0; padding:0;}

.float-right {

float:right;

148
}

.clear-both {

clear:both;

header, footer{

background:#0094ff;

padding:0 5%;

.body{

width:90%; margin:0 auto;

min-width:960px;

min-height:500px;

.mainMenu a{

color:white;

font-size:18px;

font-weight:bold;

text-decoration:none;

Chúng ta định nghĩa CSS ở mức đơn giản nhất để các bạn hiểu rõ việc xây dựng
giao diện trong ứng dụng MVC. Nếu có kiến thức về CSS thì bạn có thể hoàn toàn tự
code css để định dạng theo ý thích.

Rõ ràng là các bạn cũng cần có kiến thức sơ đẳng nhất về css để hiểu các đoạn
mã mà chúng tôi định nghĩa giao diện, một lời khuyên cho các bạn chuyển từ web form
sang MVC đó là nên tìm hiểu và học về CSS. Vì chúng là 1 phần của chìa khóa lập
trình web cho bất kỳ công nghệ nào mà có thể trừ webform cơ bản.

149
Các bạn thấy việc thiết kế layout hay trang trí giao diện trong MVC vô cùng
đơn giản.Việc định dạng CSS trong MVC gần tương đồng việc định dạng CSS trong
html tĩnh.Đó là 1 cải tiến đáng kể trong Razor so với aspx ViewEngine

21.2. Sử dụng CSS định dạng các trang kế thừa


Chúng ta làm tiếp 1 ví dụ về định dạng CSS cho các View (các trang kế thừa từ
layout ) để thấy việc định dạng giao diện trong MVC rất đơn giản hơn so với việc xử
lý định dạng kiểu kéo thả trong webform

Controller

public ActionResultIndex()

returnView();

View

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<style>

.class1 {

background:#0ff;

border:1px solid #0713f2;

margin:20px;

padding:20px;

</style>

<h2>View Index của Sample17Controller </h2>

<div class="class1">

150
Nội dung chính của trang Index

Nội dung chính của trang Index

Nội dung chính của trang Index

</div>

Chúng ta khai báo CSS trực tiếp trong các file Razor, tương tự phần trước chúng
ta có thể kahi báo trong 1 file css riêng biệt

ở đây ta định dạng trang chí cho 1 div có class là class1

Dĩ nhiên các bạn cần có kiến thức về CSS để xem các thuộc tính mà chúng tôi
định dạng.Nếu chưa có kiến thức về CSS, các bạn cần học nó hoặc tham gia khóa học
về CSS của chúng tôi.Kiến thức cơ bản CSS rất đơn giản.Chỉ cần đọc code 1 vài ngày,
và quan trọng là áp dụng vào thực tế ứng dụng thì sẽ thấy sự đơn giản của nó.

Đây là điều chắc chắn và bắt buộc.Để phát triển ứng dụng web trên bất kỳ nền
tảng nào (kể cả mã nguồn mở ) các bạn cần có kiến thức về CSS.

Trở lại ví dụ trên, chúng ta có thể khai báo mã trực tiếp CSS cho thẻ div, như
cách mà Visual Studio tự động định dạng trong webform như sau:

<div style="background:#0ff; border:1px solid #0713f2;margin:20px; paddin


g:20px;">

Nội dung chính của trang Index

Nội dung chính của trang Index

Nội dung chính của trang Index

</div>

Chạy ứng dụng ta được kết quả tương tự

21.3. Sử dụng Javascript jQuery


jQuery là thư viện javascript được hỗ trợ sẵn trong VisualStudio

Trở lại ví dụ về tính tổng hai số trong ví dụ phần trước

Dưới đây ta sẽ xử lý thuần jQuery, không xử lý tại server.

Khi đã hiểu bản chất các bạn có thể tự định hướng khi nào cần xử lý tại client,
khi nào cần xử lý tại server. Khi xử lý tại client cần chú ý tới các vấn đề bảo mật.

151
Controller:

public ActionResultIndex()

returnView();

View:

// ta code view mã html thuần như sau:

<h2>Tính tổng dùng jQuery </h2>

<div>

Kết quả:

<div id="div1"></div>

</div>

<div>

Số thứ nhất:

<input type="text" name="text1" />

</div>

<div>

Số thứ hai:

<input type="text" name="text2" />

</div>

<button>Tính tổng</button>

Bây giờ ta viết mã jQuery như sau:

<script src="~/Scripts/jquery-1.10.2.js"></script>

<script type="text/javascript">

$(function () {

152
$("#button1").click(function () {

varresult = Number($('#text1').val()) + Number($('#text2').val());

alert(result);

})

})

</script>

Toàn bộ View như sau:

<h2>Tính tổng dùng jQuery </h2>

<div>

Kết quả:

<div id="div1"></div>

</div>

<div>

Số thứ nhất:

<input type="text" name="text1" />

</div>

<div>

Số thứ hai:

<input type="text" name="text2" />

</div>

<button>Tính tổng</button>

<script src="~/Scripts/jquery-1.10.2.js"></script>

<script type="text/javascript">

$(function () {

$("#button1").click(function () {

153
varresult = Number($('#text1').val()) + Number($('#text2').val());

alert(result);

})

})

</script>

21.4. Sử dụng jQuery trong lập trình Ajax


Ajax là 1 kỹ thuật lập trình bất đồng bộ giữa Client và Sever.

Khi cần lấy thông tin dữ liệu nào đó, client chỉ cần gửi các yêu cầu (cùng những
tham số nếu có ) về phía server.Server nhận thông tin và trả về chỉ những dữ liệu cần
thiết có thể là 1 kiểu dữ liệu giá trị như 1 số, 1 chuỗi, 1 mảng.Hoặc là kiểu jSon,
html.Chứ không gửi lại toàn bộ trang web html thuần như những lời gọi tới các trang
html thông thường.

Do vậy Ajax sẽ làm tăng tốc độ giao tiếp giữa Client và server.Vì thể lập trình
ajax là 1 thành phần không thể thiếu của ứng dụng web.Tuy nhiên cũng cần chú ý không
nên lạm dụng quá nhiều, đặc biệt trong việc làm SEO website

jQuery cung cấp các phương thức hỗ trợ lập trình Ajax như:

jQuery.getJSON()

jQuery.ajax()

jQuery.get()

jQuery.post()

// Các phương thức jQuery get dữ liệu từ Server thường trả về các kiểu dữ liệu
sau:

html, text, script, xml, json

MVC có cũng cấp sẵn 1 vài Html Helper để xử lý lập trình ajax.Tuy nhiên chúng
ta có thể dùng jQuery để lập trình ajax để thấy rõ bản chất của lập trình ajax hơn.

Get dữ liệu

Controller:

public ActionResultIndex()

154
{

returnView();

public stringAjaxAction(string text)

returntext;

View Index

@{

ViewBag.Title = "Index";

Layout = "~/Views/Shared/_Layout.cshtml";

<script src="~/Scripts/jquery-1.7.1.js"></script>

<script type="text/javascript">

$(document).ready(function () {

$.get("/sample19/AjaxAction", { text: "Hello world" }, function(data) {

$("#div1").html(data);

});

});

</script>

<div id="div1"> </div>

ở đây chúng tôi lấy ví dụ đơn giản nhất để các bạn dễ đọc code.Hàm get của
jQuery ở trên gọi tới địa chỉ /sample19/ajaxAction và truyền tham số là hello world.Giá
trị trả về được lưu trong tham số data, và được thêm vào thẻ div thông qua phương thức
html của jQuery.

Với ứng dụng thực tế thường có thêm 1 vài xử lý như là lấy tham số được người
dùng nhập liệu vào các thẻ input, hay lời gọi Ajax được thực hiện khi người dùng nhấn

155
vào button trên website … Các kỹ năng này rất gần trong thực tế và các bạn chỉ cần
nắm 1 chút kiến thức về javascript – jQuery là có thể làm được.Ở đây chủ yếu là chúng
ta tìm hiểu cơ chế kết nối giữa client – server trong MVC mà không đề cập nhiều đến
jQuery

Chú ý tên tham số tại khai báo jQuery phải trùng tên tham số khai báo Action
trong Controller (ở đây tên tham số là text )

trường hợp không có tham số có thể gọi như sau:

$.get("/Home/SampleAjax",null,function(data) {

$("#div1").html(data);

ở trên Action trả về dữ liệu kiểu tham chiếu (kiểu giá trị cụ thể int, string …),
ngoài ra dữ liệu trả về trong lập trình ajax có thể là html hoặc jSon.

Ta tạo Sample20Controller

public ActionResultIndex()

returnView();

public ActionResultAjaxAction()

returnPartialView();

// chú ý AjaxAction trả về 1 PartialView (PartialView thực ra là 1 view đặc biệt,


chỉ chứa mã Razor, không kế thừa từ layout nào, và cũng không có các thẻ định
nghĩa html )

PartialView AjaxAction có code như sau:

<h1>Đây là AjaxAction PartialView </h1>

// Partial View có thể hiển thị dữ liệu từ Controller trả về như 1 View thông
thường.

156
View Index

từ View Index ta có thể gọi tới Action AjaxAction, và được trả về là các thẻ
html (partialView), ta sẽ hiển thị các thẻ này lên View Index

Ta thấy dùng Ajax thông qua jQuery ta có thể gọi tới 1 Action từ bất kỳ đâu (bất
kỳ View nào kể cả trong layout) và gọi tại bất kỳ thời điểm nào (gọi khi load trang, khi
phát sinh sự kiện …)

Post dữ liệu

// các ví dụ trên chủ yếu ta lấy dữ liệu, thông tin do server trả về.Ta có thể post
dữ liệu kiểu ajax lên server để server xử lý, server xửu lý có thể trả về hoặc không trả
về kết quả

// Cấu trúc post dữ liệu cũng tương tự get dữ liệu

[AcceptVerbs(HttpVerbs.Post)]

public stringSampleAjax(string text1)

returnstring1;

<script type="text/javascript">

$(document).ready(function () {

$.post("/Sample19/SampleAjax",{text1: "Hello world"}, function(data)

$("#div1").html(data);

});

});

</script>

<div id="div1"></div>

Các bạn thắc mắc cấu trúc của get và post gần tương tự nhau,và trong trường
hợp này mục đích và kết quả là như nhau.Ta tạm hiểu trường hợp get tức là chắc chắn

157
cần lấy dữu liệu trả về.Còn post có thể không.Giả sử ta cần gửi (post) 1 ID của Student
lên server và yêu cầu xóa Student theo ID này, ta không cần nhận lại thông báo xóa
được hay không. Khi này ta dùng post, người dùng cảm nhận website được chạy luôn
như các ứng dụng destop. Đó là kỹ thuật lập trình bất đồng bộ giữa Client và Server

158
BÀI 22. TH 7. LẬP TRÌNH MVC VỚI JSON, JQUERY

Cho giao diện website:

Yêu cầu:

- Thực hiện kết nối CSDL sử dụng Entity Framework


- Thực hiện hiển thị dữ liệu ra màn hình sử dụng điều khiển datatables và
Ajax.
- Viết các hàm cho button Add new student và Edit sử dụng các Modal popup
để thực hiện thêm, sửa thông tin bản ghi. Kết hợp sử dụng dữ liệu Ajax
- Viết sự kiện cho Action Delete để xoá bản ghi có xác nhận.

Hướng dẫn

Hướng dẫn thực hiện phần hiển thị thông tin

Bước 1: Thực hiện tạo mới CSDL

"tblDepartment"

"tblStudent"

159
Bước 2 : Tạo dự án MVC

● File”>New>Project>Visual c#>Web> Đặt tên cho dự án> then select “ok”> Chọn
“MVC”> ok.

Bước 3 : Tạo kết nối tới CSDL sử dụng Entity Framework

● Click phải “Model” chọn Add -> New Item ->ADO.NET Entity DataModel> Chọn ok -
>Generate from database ->next>New connection> Điền thông tin kết nối CSDL ->Chọn
CSDL của ->ok ->next
● Chọn các bảng CSDL bạn cần thao tác

Bước 4 : Tạo một Model để xử lý

"StudentViewModel"
public class StudentViewModel {

public int StudentId { get; set; }

public string StudentName { get; set; }

public string Email { get; set; }

public Nullable<bool> IsDeleted { get; set; }

public Nullable<int> DepartmentId { get; set; }

public string DepartmentName { get; set; }

Bước 5 : Tạo Controller để thực hiện


public class HomeController : Controller

MVCTutorialEntities db = new MVCTutorialEntities();

160
public ActionResult Index(){

//Lấy về danh sách các bộ phận

List<tblDepartment> DeptList = db.tblDepartments.ToList();

ViewBag.ListOfDepartment = new SelectList(DeptList, "DepartmentId",


"DepartmentName");

return View();

public JsonResult GetStudentList(){

//Lấy về thông tin của sinh viên

List<StudentViewModel> StuList = db.tblStudents.Where(x => x.IsDeleted ==


false).Select(x => new StudentViewModel {StudentId = x.StudentId, StudentName = x.StudentName,
Email = x.Email, DepartmentName = x.tblDepartment.DepartmentName }).ToList();

return Json(StuList, JsonRequestBehavior.AllowGet);

Bước 6 : Tạo View hiển thị


@model FullCRUDImplementationWithJquery.Models.StudentViewModel

@{Layout = null; }

<script src="~/Scripts/jquery-1.10.2.min.js"></script>

<script src="~/Scripts/bootstrap.min.js"></script>

<link href="~/Content/bootstrap.min.css" rel="stylesheet" />

<div class="container" style="margin-top:3%">

<a href="#" class="btn btn-info" onclick="AddNewStudent(0)">Add New Student</a> <br


/><br />

<table class="table table-striped">

<thead>

<tr>

<th>Student ID</th>

<th>Student Name</th>

161
<th>Email</th>

<th>Department</th>

<th>Action(Edit)</th>

<th>Action(Delete)</th>

</tr>

</thead>

<tbody id="SetStudentList">

<tr id="LoadingStatus" style="color:red"></tr>

</tbody>

</table>

</div>

<script>

$("#LoadingStatus").html("Loading...."); $.get("/Home/GetStudentList", null, DataBind);

function DataBind(StudentList) {//Đoạn code hiển thị danh sách sinh viên

var SetData = $("#SetStudentList");

for (var i = 0; i < StudentList.length; i++) {

var Data = "<tr class='row_" +

StudentList[i].StudentId + "'>" +

"<td>" + StudentList[i].StudentId + "</td>" +

"<td>" + StudentList[i].StudentName + "</td>" +

"<td>" + StudentList[i].Email + "</td>" +

"<td>" + StudentList[i].DepartmentName + "</td>" +

"<td>" + "<a href='#' class='btn btn-warning' onclick= 'EditStudentRecord(" +

StudentList[i].StudentId + ")' ><span class='glyphicon glyphicon-edit'></span></a>" +


"</td>" +

"<td>" + "<a href='#' class='btn btn-danger' onclick='DeleteStudentRecord(" +


StudentList[i].StudentId + ")'><span class='glyphicon glyphicon-trash'></span></a>" + "</td>" +

"</tr>";

SetData.append(Data);

162
$("#LoadingStatus").html(" ");

</script>

Phần tự làm

Sinh viên tự làm phần thêm, sửa, xoá sử dụng modal popup để thực hiện

Bài 1: Hiển thị danh sách cán bộ (bao gồm họ tên, địa chỉ, điện thoại) trong
bảng tblCanBo. Trong đó Họ tên chữ đậm.
Hướng dẫn:

- Đặt thuộc tính AutoGenerateColumns = "false" 



- Tự tạo các cột cho GridView bằng cặp thẻ <asp:TemplateField> ...</>

- Đặt nội dung cần hiển thị (ở đây là Họ tên, địa chỉ, điện thoại) vào các
cột bằng 
cách
đặt bên trong cặp thẻ <asp:DataItemTemplate> </>

Bài 2: Bổ sung thêm trường Photo vào bảng tblCanBo, trường Photo này sẽ lưu
đường dẫn tới file ảnh của mỗi cán bộ. Sau đó xây dựng trang web hiển thị thông tin
cán bộ (bao gồm các trường Họ tên, địa chỉ và ảnh tương ứng).
Hướng dẫn:

- Vì trường Photo đã chứa đường dẫn đến file ảnh rồi, vì vậy để hiển thị
hình ảnh thay vì văn bản text thuần túy, ta sẽ tạo thêm phần tử
<asp:Image>, trong đó thuộc tính ImageUrl sẽ được gán giá trị của
trường Photo tương ứng. cụ thể là : 
<asp:Image ID="Image1"
runat="server" ImageUrl='<%# Eval("Photo") %>' /> 

- Để đặt kích thước ảnh như nhau, có thể thêm thuộc tính Width và Height

- Trước giá trị <%# Eval("Photo") %> cần có thêm cặp dấu nháy đơn để
đảm bảo 
tính đúng đắn khi đường dẫn ảnh chứa dấu cách. 


Bài 3: Hiển thị danh sách cán bộ dạng chi tiết. Thông tin được dàn trang theo
chiều dọc (Flow).
Hướng dẫn: Tạo một cột duy nhất, nhưng mỗi dòng của cột đó sẽ
chứa tất cả các trường thông tin cần hiển thị. Với mỗi hàng được tạo ra, ta sẽ đặt vào
một table có kích thước cố định, bảng này có 1 hàng và 2 cột. Cột thứ nhất sẽ chứa
thông tin ở dạng text như họ tên, địa chỉ, điện thoại và mô tả bản thân. Cột thứ hai sẽ
hiển thị hình ảnh tương ứng.

Bài 4: Hiển thị thông tin trích ngang về người dùng trong bảng tblUser, trong
đó dưới mỗi người dùng thêm một Hyperlink là "Xem chi tiết" để khi người dùng click
vào hyperlink này thì mở trang UserDetail.aspx và hiển thị chi tiết thông tin về người
dùng đó. Yêu cầu thêm: Danh sách này hiển thị làm 3 cột.

163
Hướng dẫn: Để hiển thị thông tin dưới dạng cột, ta sử dụng điều khiển DataList.
Trong mỗi Hyperlink ta sẽ tạo liên kết đến trang UserDetail.aspx và truyền cho trang
này ID (trong trường hợp này là TenDangNhap) của người dùng tương ứng. Dựa vào
ID này, trang UserDetail.aspx sẽ đọc (dùng Request.QueryString["TenNguoiDung"])
sau đó select thông tin ứng với ID đó và hiển thị.

Bài tập

Sử dụng Crystal report để xuất báo cáo dữ liệu trên datatables như hình sau:

164
Hướng dẫn:

Tạo CSDL

CREATE TABLE [dbo].[Customers](

[CustomerID] [int] NOT NULL,

[CustomerName] [varchar](50) NULL,

[CustomerEmail] [varchar](50) NULL,

[CustomerZipCode] [int] NULL,

[CustomerCountry] [varchar](50) NULL,

[CustomerCity] [varchar](50) NULL,

CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED

Bước 2. Tạo Entity Framework kết nối đến CSDL

Bước 3. Thiết kế Crystal report

Bước 4. Tạo Controller

namespace CrystalReportMVC.Controllers

public class CustomerController : Controller

//DbContext

private CustomerDBEntities context = new CustomerDBEntities();

// GET: Customer

public ActionResult Index()

var customerList = context.Customers.ToList();

return View(customerList);

165
}
public ActionResult ExportCustomers()
{
List<Customer> allCustomer = new List<Customer>();
allCustomer = context.Customers.ToList();

ReportDocument rd = new ReportDocument();


rd.Load(Path.Combine(Server.MapPath("~/CrystalReports"), "ReportC
ustomer.rpt"));

rd.SetDataSource(allCustomer);
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
Stream stream = rd.ExportToStream(CrystalDecisions.Shared.Expor
tFormatType.PortableDocFormat);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/pdf", "CustomerList.pdf");
}
}
}
Bước 5. Tạo View hiển thị
@model IEnumerable<CrystalReportMVC.Customer>
@{
ViewBag.Title = "Index";
}
<h2>Customers List</h2>

166
<p>
@Html.ActionLink("Create New", "Create")
<div><a href="@Url.Action("ExportCustomers")"> Report PDF </a></div
>

</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.CustomerName)
</th>
<th>
@Html.DisplayNameFor(model => model.CustomerEmail)
</th>
<th>
@Html.DisplayNameFor(model => model.CustomerZipCode)
</th>
<th>
@Html.DisplayNameFor(model => model.CustomerCountry)
</th>
<th>
@Html.DisplayNameFor(model => model.CustomerCity)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>

167
@Html.DisplayFor(modelItem => item.CustomerName)
</td>
<td>
@Html.DisplayFor(modelItem => item.CustomerEmail)
</td>
<td>
@Html.DisplayFor(modelItem => item.CustomerZipCode)
</td>
<td>
@Html.DisplayFor(modelItem => item.CustomerCountry)
</td>
<td>
@Html.DisplayFor(modelItem => item.CustomerCity)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.CustomerID }) |
@Html.ActionLink("Details", "Details", new { id=item.CustomerID })
|
@Html.ActionLink("Delete", "Delete", new { id=item.CustomerID })
</td>
</tr>
}
</table>

168
BÀI 23. TH 8. KIỂM TRA THỰC HÀNH
Câu 01: Dùng Server Controll và thẻ html hiển thị dữ liệu theo hình 1

Hình 1: Danh sách nhóm

Câu 02: Thiết kế giao diện nhập dữ liệu người dùng được mô tả trong hình
2 sử dụng các thẻ: form, table, input và các thuộc tính của các thẻ html.

Hình 2: Thêm nhóm ngưòi dùng


Câu 03: Thực hiện lập trình nhận dữ liệu và thêm dữ liệu vào CSDL sử
dụng các đối tượng của ADO.NET với các thông dtin như sau:

"Data source=127.0.0.1; initial catalog=db01; user id = sa; password =123"

169

You might also like