Xem mẫu
- 1.1 Sử dụng page-caching và fragment-caching
Bạn cần tăng hiệu năng bằng cách lưu giữ các trang được trả về.
Thêm chỉ thị OutputCache vào trang hoặc điều kiểm người dùng, và chỉ định
trang sẽ được giữ trong cache bao lâu (tính theo giây).
Việc sử dụng caching vừa phải có thể giảm bớt hiệu ứng thắt cổ chai (chẳng hạn, truy
xuất cơ sở dữ liệu) và tăng toàn bộ hiệu năng của một website. Caching có hiệu quả lớn
trong một site có lưu lượng cao. Ví dụ, xét xem điều gì sẽ xảy ra khi bạn lưu giữ một
trang hiển thị kết quả của một truy vấn cơ sở dữ liệu. Nếu bạn lưu giữ trang này trong 1
phút, và trang này nhận được 10 yêu cầu trong khoảng thời gian đó, bạn sẽ giảm được 10
lần chi phí truy xuất cơ sở dữ liệu.
Bạn có thể hiện thực caching một cách dễ dàng—chỉ cần thêm chỉ thị OutputCache vào
trang web. Chỉ thị này phải được thêm vào file .aspx, chứ không phải file .cs. Ví dụ dưới
đây lưu giữ một trang trong 20 giây:
Và ví dụ dưới đây lưu giữ một trang trong 20 giây nhưng vẫn duy trì các bản sao tùy vào
giá trị của các đối số chuỗi truy vấn:
Bạn có thể thử nghiệm caching bằng một trang hiển thị ngày và giờ trên server. Bạn sẽ
nhận thấy rằng các yêu cầu đến sau (đối với trang này) không khiến cho thời gian được
tạo mới. Theo đó, thời gian cũ sẽ được hiển thị cho đến khi trang hết hiệu lực.
Output-caching không hiệu quả trong các trường hợp sau đây:
• Trang của bạn cần tự tùy biến y theo các thiết lập đặc thù của người dùng như thông
tin xác thực (đối tượng User) hoặc trạng thái (đối tượng Session). Trong trường hợp
này, nó không tạo cảm giác sử dụng lại cùng một trang cho tất cả các người dùng.
• Trang của bạn chứa các điều kiểm post-back và dựng nên các sự kiện phía server.
• Trang của bạn cần thực hiện một hành động khác (như ghi ra file nhật ký, nhập
thông tin vào cơ sở dữ liệu, hoặc thay đổi một biến ứng dụng). Một trang được lưu
giữ sẽ sử dụng lại toàn bộ HTML đã được trả về; phần mã cho trang bị bỏ qua.
• Trang của bạn có chứa các dữ liệu cần phải được tạo cùng với các dữ liệu hiện hành.
Đây là trường hợp đối với tìm kiếm sản phẩm, nhưng không phải là trường hợp đối
với danh mục sản phẩm.
Trong các trường hợp này, bạn có thể sử dụng một dạng caching linh hoạt hơn. Bạn có
thể sử dụng data-caching (sẽ được mô tả trong mục 7.15) để lưu giữ một đối tượng cụ
thể. Hoặc bạn có thể sử dụng fragment-caching để lưu giữ một phần của trang. Để sử
dụng fragment-caching, bạn cần tạo một điều kiểm người dùng chứa tất cả nội dung có
- thể được lưu giữ và thêm chỉ thị OutputCache vào điều kiểm người dùng. Khi đó, bạn có
thể sử dụng điều kiểm người dùng này trong một trang web. Phần mã cho trang web vẫn
sẽ chạy, nhưng phần điều kiểm người dùng có thể được lưu giữ.
1.2 Dùng lại dữ liệu với ASP.NET Cache
Bạn cần sử dụng caching, nhưng bạn không thể lưu giữ toàn bộ một trang vì nó
chứa một số mã cần phải chạy hoặc một số nội dung cần phải được tạo động.
Sử dụng phương thức Cache.Insert để lưu giữ bất kỳ đối tượng nào với chính
sách hết hiệu lực trượt (sliding expiration) hoặc hết hiệu lực tuyệt đối (absolute
expiration).
Đối tượng Cache cho phép bạn lưu giữ hầu như bất kỳ đối tượng .NET nào bằng một
khóa chuỗi cùng với chính sách hết hiệu lực do bạn định nghĩa. ASP.NET duy trì cache
một cách tự động, gỡ bỏ các đối tượng khi chúng hết hiệu lực hoặc khi cạn bộ nhớ.
Có hai kiểu chính sách hết hiệu lực bạn có thể sử dụng khi lưu giữ dữ liệu trong cache.
Hết hiệu lực tuyệt đối (absolute expiration) làm mất hiệu lực các item đã được lưu giữ
sau một khoảng thời gian cố định, gần giống với output-caching. Hết hiệu lực tuyệt đối là
cách tiếp cận tốt nhất nếu bạn muốn lưu giữ các thông tin cần được làm tươi định kỳ (như
danh mục sản phầm).
// Lưu giữ ObjectToCache trong 10 phút (với khóa là "Catalog").
// TimeSpan.Zero cho biết "không sử dụng sliding expiration".
Cache.Insert("Catalog", ObjectToCache, null,
DateTime.Now.AddMinutes(10), TimeSpan.Zero);
Hết hiệu lực trượt (sliding expiration) gỡ bỏ các đối tượng sau một khoảng thời gian
không dùng đến. Trong trường hợp này, mỗi khi đối tượng được truy xuất, thời gian sống
của nó sẽ được reset. Hết hiệu lực trượt làm việc tốt khi bạn có các thông tin luôn có hiệu
lực nhưng luôn không được sử dụng (như dữ liệu thuộc về quá khứ). Thông tin này
không cần được làm tươi, nhưng không nên giữ nó trong cache nếu nó không được sử
dụng.
// Lưu giữ ObjectToCache nếu nó được sử dụng ít nhất
// một lần mỗi 10 phút (với khóa là "Catalog").
// DateTime.MaxValue cho biết "không sử dụng absolute expiration".
Cache.Insert("Catalog", ObjectToCache, null,
DateTime.MaxValue, TimeSpan.FromMinutes(10));
Bạn có thể lấy các item từ cache bằng tên khóa. Tuy nhiên, bạn phải luôn kiểm tra trước
xem item có tồn tại hay không và rồi ép nó thành kiểu như mong muốn.
Khi thêm các đối tượng vào cache, cách tốt nhất là tạo một hàm độc lập có thể tái tạo đối
tượng khi cần. Ví dụ, nếu đang lưu giữ một DataSet, bạn cần tạo một hàm kiểm tra cache
- và chỉ truy vấn lại cơ sở dữ liệu khi không tìm thấy DataSet. Điều này cho phép bạn tránh
đi phần xử lý tốn nhiều thời gian nhất—truy vấn cơ sở dữ liệu—trong khi vẫn cho phép
mã lệnh của bạn thay đổi hiển thị (chẳng hạn, người dùng yêu cầu sắp thứ tự) hoặc thực
hiện các hành động khác.
Ví dụ dưới đây sẽ hiển thị một bảng chứa thông tin về khách hàng được lấy từ một
DataSet. Phần then chốt là lớp CustomerDatabase, đóng gói các chức năng cần thiết để
đổ dữ liệu vào DataSet và quản lý cache. Vì lớp này không thừa kế từ Page nên nó cần sử
dụng thuộc tính tĩnh HttpContext.Current để lấy tham chiếu đến đối tượng Cache.
using System;
using System.Data;
using System.Web;
using System.Configuration;
using System.Diagnostics;
using System.Web.Caching;
using System.Data.SqlClient;
public class CustomerDatabase {
private string connectionString;
// Lấy tham chiếu đến đối tượng Cache.
private Cache cache = HttpContext.Current.Cache;
public CustomerDatabase() {
// Lấy chuỗi kết nối từ file Web.config.
connectionString =
ConfigurationSettings.AppSettings["NorthwindCon"];
}
public DataSet GetCustomers() {
DataSet customersDS;
// Kiểm tra item có nằm trong cache hay không.
if (cache["Customers"] == null) {
// Lấy DataSet từ cơ sở dữ liệu.
customersDS = GetCustomersFromDatabase();
- // Lưu giữ item trong cache
// cùng với sliding expiration là 60 giây.
cache.Insert("Customers", customersDS, null,
DateTime.MaxValue, TimeSpan.FromSeconds(60));
// Hiển thị thông điệp trong cửa sổ Debug.
Debug.WriteLine("DataSet created from data source.");
}else {
// Hiển thị thông điệp trong cửa sổ Debug.
Debug.WriteLine("DataSet retrieved from cache.");
// Lấy item.
customersDS = (DataSet)cache["Customers"];
}
// Trả về DataSet.
return customersDS;
}
private DataSet GetCustomersFromDatabase() {
// Tạo DataSet.
DataSet customersDS = new DataSet();
// Đổ dữ liệu vào DataSet.
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("SELECT * FROM Customers", con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
try {
con.Open();
adapter.Fill(customersDS, "Customers");
}catch {
customersDS = null;
- }
finally {
con.Close();
}
Bước kế tiếp là tạo một trang web sử dụng lớp CustomerDatabase. Trang web dưới đây
gồm một DataGrid và một Button. Mỗi khi người dùng nhắp vào Button, trang sẽ gọi
phương thức CustomerDatabase.GetCustomers. Thông tin được lấy từ cache nếu vẫn còn
hiệu lực hoặc được truy vấn lại nếu 60 giây đã trôi qua. Bạn có thể nhận biết DataSet có
được lấy từ cache hay không bằng cách nhìn vào kết xuất trong cửa sổ Debug.
using System;
using System.Web;
using System.Web.UI.WebControls;
public class LoginPage : System.Web.UI.Page {
protected System.Web.UI.WebControls.DataGrid DataGrid1;
protected System.Web.UI.WebControls.Button cmdGetData;
// (Bỏ qua phần mã designer.)
private void cmdGetData_Click(object sender, System.EventArgs e){
CustomerDatabase custDB = new CustomerDatabase();
DataGrid1.DataSource = custDB.GetCustomers();
DataGrid1.DataBind();
}
}
1.3 Kích hoạt việc gỡ rối ứng dụng Web
Khi thực hiện gỡ rối một ứng dụng Web với Visual Studio .NET, bạn nhận được
lỗi “Unable to start debugging on the Web server”.
Bảo đảm Internet Information Services (IIS) được cài đặt đúng, IIS được cài đặt
trước Microsoft .NET Framework, và Integrated Windows authentication được
kích hoạt cho thư mục chứa ứng dụng Web.
Lỗi “Unable to start debugging on the Web server” cho biết rằng Visual Studio .NET có
thể biên dịch ứng dụng Web nhưng không thể thực thi nó ở chế độ gỡ rối (debug mode).
Vấn đề này phát sinh vì nhiều lý do:
- • IIS chưa được cài đặt hoặc cài đặt không đúng.
• Người dùng đang chạy Visual Studio .NET không phải là thành viên của nhóm
Debugger Users trên web-server.
• Người dùng đang chạy Visual Studio .NET không có quyền (permission) gỡ rối tiến
trình ASP.NET. Ví dụ, nếu tiến trình ASP.NET đang chạy dưới tài khoản hệ thống
cục bộ, người dùng phải có đặc quyền Administrator thì mới có thể gỡ rối nó.
• Web-server đang chạy trên phiên bản Windows không hỗ trợ gỡ rối, như Microsoft
Windows NT và Windows XP Home Edition (Windows 2000, Windows XP
Professional, Windows XP Server, và Windows Server 2003 đều hỗ trợ gỡ rối).
• Ứng dụng Web không có file Web.config, hoặc file Web.config không kích hoạt gỡ
rối.
• Bạn đang chạy Visual Studio .NET, và bạn không kích hoạt Integrated Windows
authentication cho thư mục ảo.
Bước đầu tiên bạn cần thực hiện khi chẩn đoán lý do không thể gỡ rối một ứng dụng Web
là kiểm tra việc cài đặt IIS trên web-server. Để thực hiện điều này, bạn hãy mở
http://localhost/localstart.asp trong trình duyệt (localhost là một bí danh cho máy tính
hiện hành). Nếu trang thử nghiệm này không xuất hiện thì có nghĩa là IIS không được cài
đặt hoặc không được kích hoạt. Bạn cũng có thể bắt đầu ứng dụng Web mà không thực
hiện gỡ rối bằng cách chọn Debug | Start Without Debugging từ thanh trình đơn của
Visual Studio .NET. Nếu thử nghiệm này thành công thì có nghĩa là IIS đã được cài đặt
đúng.
Nếu cài đặt IIS sau khi cài đặt Visual Studio .NET hoặc .NET Framework, bạn cần phải
"sửa" .NET Framework bằng đĩa cài đặt gốc. Để bắt đầu quá trình này, bạn hãy gõ lệnh
sau đây vào cửa sổ dòng lệnh (hoặc cửa sổ Run), nếu đang dùng phiên bản DVD của
Visual Studio .NET:
:\wcu\dotNetFramework\dotnetfx.exe /t:c:\temp
/c:"msiexec.exe /fvecms c:\temp\netfx.msi"
Nếu đang dùng phiên bản CD của Visual Studio .NET, bạn hãy sử dụng dòng lệnh sau
đây cùng với đĩa Windows Component Update:
:\dotNetFramework\dotnetfx.exe /t:c:\temp
/c:"msiexec.exe /fvecms c:\temp\netfx.msi"
Nếu IIS được cài đặt đúng, bước kế tiếp là xác nhận tính hợp lệ của file Web.config. File
Web.config phải có cấu trúc như sau:
-
Theo mặc định, Visual Studio .NET thêm thẻ vào file Web.config (được
tạo tự động) với đặc tính debug được thiết lập là true.
Bước kế tiếp là kiểm tra cấu hình IIS. Vấn đề sẽ xảy ra nếu bạn quên tạo thư mục ảo cho
ứng dụng hoặc nếu bạn chạy một ứng dụng sau khi đã gỡ bỏ hoặc chỉnh sửa thư mục ảo
của nó. Để khắc phục các vấn đề này, bạn hãy hiệu chỉnh các thiết lập cho thư mục ảo
trong IIS Manager bằng cách chọn Control Panel | Administrative Tools | Internet
Information Services từ Start Menu. Bạn cần kiểm tra xem thư mục ảo đã tồn tại và được
cấu hình là một ứng dụng Web hay chưa (bạn có thể xem các thiết lập cho thư mục ảo
bằng cách nhắp phải vào nó và chọn Properties). Ví dụ, thư mục ảo FMStocks7 (xem
hình 7.12) đã tồn tại nhưng chưa được cấu hình là một ứng dụng Web. Để giải quyết vấn
đề này, bạn chỉ cần nhắp vào nút Create trong phần Application Settings.
Một vấn đề khác về cấu hình IIS có thể xảy ra trong Visual Studio .NET là không thực
hiện xác thực. Visual Studio .NET truy xuất web-server cục bộ bằng Integrated Windows
authentication, ngay cả khi bạn đã kích hoạt Anonymous authentication cho thư mục ảo.
Điều này nghĩa là thư mục ảo của bạn phải cho phép cả Anonymous authentication và
Integrated Windows authentication. Để cho phép cả hai phương pháp này, bạn cần thực
hiện các bước sau đây:
1. Trong IIS Manager, nhắp phải vào thư mục ảo cho ứng dụng của bạn và chọn
Properties (bạn có thể cấu hình kiểu xác thực cho tất cả các thư mục nếu nhắp phải
vào thư mục Web Sites và chọn Properties).
2. Chọn thẻ Directory Security (xem hình 7.13).
3. Trong phần Anonymous access and authentication control, nhắp nút Edit.
4. Trong hộp thoại Authentication Methods, bên dưới Authenticated access, chọn
Integrated Windows authentication (xem hình 7.14).
5. Nhắp OK.
1.4 Thay đổi quyền đã cấp cho mã ASP.NET
- Bạn cần cấp cho phần mã của trang web hoặc dịch vụ Web của bạn nhiều đặc
quyền Windows hơn (như các quyền cho file, thiết lập Registry, cơ sở dữ liệu, và
các tài nguyên khác), hoặc bạn cần hạn chế các đặc quyền hiện có.
Bạn có thể gán trực tiếp các đặc quyền cho tài khoản ASPNET cục bộ, hoặc có
thể cấu hình mã ASP.NET của bạn để sử dụng một tài khoản hoàn toàn khác
bằng cách chỉnh sửa thẻ trong file machine.config. Bạn cũng
có thể sử dụng kỹ thuật giả nhận (impersonation) để một đoạn mã thực thi với
các quyền của người dùng đã được IIS xác thực.
Mã ASP.NET không chạy dưới tài khoản người dùng đã được IIS xác thực hoặc tài khoản
nặc danh IUSR_[ServerName]. Một phần lý do là tài khoản này thường không có đủ đặc
quyền đối với mã ASP.NET (có thể tạo và xóa các file tạm để quản lý tiến trình biên dịch
trang web).
Theo mặc định, các trang ASP.NET chạy bằng tài khoản ASPNET cục bộ, tài khoản này
có một tập các đặc quyền bị giới hạn. Nếu cần mã ASP.NET của bạn thực hiện điều gì đó
không được phép theo mặc định đối với tài khoản cục bộ (chẳng hạn, ghi ra ổ đĩa cứng
trên server), bạn có thể cấp các quyền này cho tiến trình ASPNET. Bạn cũng có thể thay
đổi thiết lập này bằng cách mở file machine.config (nằm trong thư mục \Microsoft.NET\ Framework\\CONFIG\) và chỉnh sửa thẻ
.
The image part with relationship ID rId5 was not found in the file.
Hình 7.15 File machine.config
Bạn có thể thiết lập các đặc tính userName và password cho một người dùng bất kỳ, hoặc
bạn có thể đưa vào sử dụng tiến trình ASPNET cục bộ (thiết lập userName là machine và
password là AutoGenerate) hoặc tài khoản hệ thống cục bộ (thiết lập userName là
SYSTEM và password là AutoGenerate). Vì tài khoản hệ thống cục bộ có có đầy đủ
quyền trên máy tính nên đừng bao giờ sử dụng tài khoản này ngoại trừ mục đích thử
- nghiệm. Các thiết lập về tài khoản ASP.NET là toàn cục và tất cả các ứng dụng Web sẽ
chia sẻ tài khoản mà bạn chỉ định.
Bạn cũng có thể thay đổi tài khoản dùng để thực thi các ứng dụng hoặc đoạn mã nào đó
bằng kỹ thuật giả nhận. Ví dụ, để cấu hình một ứng dụng Web chạy dưới một tài khoản
người dùng khác, bạn cần thêm thẻ vào file Web.config như sau:
Bạn cũng có thể chỉ thị ứng dụng Web sử dụng identity đã được IIS xác thực, đó sẽ là tài
khoản nặc danh IUSR_[ServerName] nếu bạn không sử dụng Windows authentication (đã
được thảo luận trong mục 7.8). Bạn chỉ cần thêm thẻ mà không phải thêm bất
cứ thông tin xác thực nào:
Nhớ rằng, đối với kiểu giả nhận này, tài khoản người dùng sẽ yêu cầu truy xuất đọc/ghi
đến thư mục Temporary ASP.NET Files (nơi lưu trữ các file ASP.NET đã được biên
dịch—được định vị tại \[WindowsDirectory]\Microsoft.NET\Framework[version]\Temporary ASP.NET Files).
Cuối cùng, bạn cũng có thể sử dụng kỹ thuật giả nhận bằng mã lệnh (vấn đề này sẽ được
mô tả chi tiết trong mục 13.15). Tuy vậy, ví dụ dưới đây sẽ làm việc cùng với Windows
authentication. Nếu IIS đã xác thực người dùng (được mô tả trong mục 7.8), identity đó
sẽ được thừa nhận khi sử dụng phương thức WindowsIdentity.Impersonate. Để sử dụng
đoạn mã này, bạn phải nhập không gian tên System.Security.Principal.
if (User.GetType() == typeof(WindowsPrincipal)) {
WindowsIdentity id = (WindowsIdentity)User.Identity;
WindowsImpersonationContext impersonate = id.Impersonate();
// (Thực hiện các tác vụ với ID này.)
// Trả lại ID.
impersonate.Undo();
} else {
- // Người dùng không được xác thực.
// Ném lỗi hoặc thực hiện các bước khác.
}
nguon tai.lieu . vn