tác vụ
Bài viết được cập nhật từ 2:02:05 CH, 05 Tháng Chín 2012 bởi tumivn
Với bài thứ 8 trong loạt bài hướng dẫn nhập môn với ASP.NET MVC, chúng ta sẽ tham khảo action Edit của TaskController, đây là một action được sinh ra bởi Visual Studio. Sau đó chúng ta sẽ lập trình thêm một trang hỗ trợ tìm kiếm tác vụ.
Bạn hãy chạy ứng dụng và sau đó duyệt địa chỉ /Task/Index, tiếp đó tại danh sách các tác vụ, bạn hãy rê chuột đến link Edit của một tác vụ bất kỳ:
Bạn sẽ thấy ở phía bên dưới sẽ xuất hiện địa chỉ của link mà bạn rê chuột lên, ở trong hình là
/Task/Edit/4, nghĩa là link sẽ được action Edit của TaskController xử lý và tham số truyền vào có tên là id với giá trị là 4.
Link Edit được sinh ra bởi phương thử Html.ActionLink được sử dụng bên trong tập tin Views/Task/Index.cshtml:
@Html.ActionLink("Edit", "Edit", new { id=item.Id })
Đối tượng Html là một thuộc tính của lớp WebViewPage, lớp này là lớp gốc mà các lớp quản lý view kế thừa. Phương thức ActionLink của đối tượng Html giúp tạo ra các siêu liên kết một cách tự động
dựa trên các action của Controller.
Ví dụ, trong mã lệnh trên, tham số đầu tiên là chuỗi được hiển thị bên trong của siêu liên kết, tham số thứ hai là tên của action là Edit, tham số thứ 3 là danh sách các giá trị được truyền lên cho action. Controller ở đây được mặc định là TaskController, vì mã tạo link được sử dụng trên view Index.cshtml
của action Index của TaskController, nên nó nhận TaskController là controller mặc định.
Ngoài cách tạo hyperlink dạng /Task/Edit/4, bạn có thể truy xuất /Task/Edit?id=4, hai link này đều điều hướng đến cùng một action là Edit của TaskController.
Hãy mở mã lệnh của TaskController, chúng ta sẽ thấy hai phương thức Edit như sau:
// GET: /Task/Edit/5
{
Task task = db.Tasks.Find(id); return View(task);
} //
// POST: /Task/Edit/5
[HttpPost]
public ActionResult Edit(Task task) {
if (ModelState.IsValid) {
db.Entry(task).State = EntityState.Modified; db.SaveChanges();
return RedirectToAction("Index"); }
return View(task); }
Phương thức thứ hai là phương thức có gắn thuộc tính [HttpPost], điều này có nghĩa là nó chỉ nhận các request dạng POST, các request dạng khác (như DELETE, PUT, GET..) sẽ không được điều hướng đến phương thức này. Điều này cũng có nghĩa là đối với các request dạng Get phương thức thứ nhất sẽ tiếp nhận, và phương thức thứ hai sẽ tiếp nhận các request dạng POST.
Bạn cũng có thể áp dụng thuộc tính (attribute) [HttpGet] đối với các action mà bạn chỉ muốn nó xử lý các request dạng GET được gởi lên từ trình duyệt mà thôi.
Phương thức thứ nhất, dùng để tiếp nhận các request dạng GET, sử dụng phương thức Find của Entity Framework để trả về đối tượng Task cho view. Khi sinh ra TaskController, Visual Studio đã sinh ra view Edit.cshtml, mã sinh ra của view này như sau:
@model ToDoApp.Models.Task @{ ViewBag.Title = "Edit"; } <h2>Edit</h2> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset>
<legend>Task</legend>
@Html.HiddenFor(model => model.Id) <div class="editor-label">
@Html.LabelFor(model => model.Content) </div>
<div class="editor-field">
@Html.EditorFor(model => model.Content)
@Html.ValidationMessageFor(model => model.Content) </div>
<div class="editor-label">
@Html.LabelFor(model => model.CreateDate) </div>
<div class="editor-field">
@Html.EditorFor(model => model.CreateDate)
@Html.ValidationMessageFor(model => model.CreateDate) </div>
<div class="editor-label">
@Html.LabelFor(model => model.DueDate) </div>
<div class="editor-field">
@Html.EditorFor(model => model.DueDate)
@Html.ValidationMessageFor(model => model.DueDate) </div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Ở phía trên cùng của tập tin là dòng mã lệnh:
@model ToDoApp.Models.Task
Dòng lệnh nói trên cho biết rằng, view sẽ nhận Model là một đối tượng thuộc lớp Task.
Visual Studio đã sử dụng các phương thức của thuộc tính Html như Html.LabelFor(), Html.EditorFor() để sinh ra các mã HTML nhằm hiển thị các tiêu đề cũng như các thẻ <input> cho phép người dùng
nhập nội dung liên quan đến đối tượng Task.
Html.ValidationSummary() để hiển thị các lỗi khi kiểm tra tính hợp lệ của dữ liệu được nhập vào. Trong trường hợp dữ liệu được nhập vào không hợp lệ, sẽ có các thông báo lỗi xuất hiện tại các vị trí
tương ứng.
Để xem mã HTML được sinh ra như thế nào, bạn có thể nhấp chuột phải vào trang /Task/Edit/4 đang xem và chọn xem mã nguồn HTML. Mã HTML được sinh ra khi áp dụng view Edit.cshtml như sau:
<!DOCTYPE html> <html>
<head>
<meta charset="utf-8" />
<title>Edit</title>
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> <script src="/Scripts/modernizr-1.7.min.js" type="text/javascript"></script> </head> <body>
<div class="page">
<header>
<div id="title">
<h1>To Do App</h1>
</div>
<div id="logindisplay">
[ <a href="/Account/LogOn">Log On</a> ] </div>
<nav>
<ul id="menu">
<li><a href="/">Home</a></li>
<li><a href="/Home/About">About</a></li>
</ul> </nav> </header> <section id="main"> <h2>Edit</h2>
<script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script> <script src="/Scripts/jquery.validate.unobtrusive.min.js"
type="text/javascript"></script>
<form action="/Task/Edit/4" method="post"> <fieldset>
<legend>Task</legend>
<input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Id" name="Id"
type="hidden" value="4" />
<label for="Content">Content</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Content" name="Content"
type="text" value="Creating a blog engine using PHP Code Ignitor" />
<span class="field-validation-valid" data-valmsg-for="Content"
data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="CreateDate">CreateDate</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-
required="The CreateDate field is required." id="CreateDate" name="CreateDate"
type="text" value="9/3/2012 12:00:00 AM" />
<span class="field-validation-valid" data-valmsg-for="CreateDate"
data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="DueDate">DueDate</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val- required="The DueDate field is required." id="DueDate" name="DueDate"
type="text" value="9/12/2012 12:00:00 AM" />
<span class="field-validation-valid" data-valmsg-for="DueDate"
data-valmsg-replace="true"></span>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset> </form>
<div>
<a href="/Task">Back to List</a> </div> </section> <footer> </footer> </div> </body> </html> Xử lý POST Request
Mã lệnh của action Edit dành cho việc xử lý các Request dạng POST như sau:
[HttpPost]
public ActionResult Edit(Task task) {
if (ModelState.IsValid) {
db.Entry(task).State = EntityState.Modified; db.SaveChanges();
return RedirectToAction("Index"); }
return View(task); }
Phương thức trên nhận đối tượng Task làm tham số, vậy tham số Task này được lấy từ đâu ra? Chúng ta có thể hiểu các thao tác như sau, khi người dùng nhập nội dung vào các thẻ <input> ở trình duyệt và nhất nút Submit, thì form chứa các thông tin được nhập để điều chỉnh sẽ được gởi lên server, và POST Request này sẽ được điều hướng để phương thức Edit nói trên tiếp nhận, đối tượng task sẽ được ASP.NET MVC ánh xạ từ các giá trị được truyền lên bởi POST Request.
Hình phía trên là chính là thông tin về các tham số mà một POST Request được gởi lên server khi người dùng nhập dữ liệu để điều chỉnh một tác vụ. Bạn sẽ thấy các tham số được gởi lên có tên tương ứng với các thuộc tính của đối tượng Task và vì vậy nó được ASP.NET MVC ánh xạ một cách dễ dàng để trở thành tham số task và đưa vào lời gọi phương thức Edit ở trên.
Khi action Edit phiên bản HttpPost được gọi, nó sẽ kiểm tra đối tượng Task được truyền vào có hợp lệ hay không bằng cách sử dụng phương thức ModelState.IsValid, phương thức này sẽ duyệt qua từng trường của Model (ở đây là một đối tượng kiểu Task) và kiểm tra từng trường một xem thử nó có hợp lệ không, nếu có ít nhất một trường không hợp lệ, ModelState.IsValid sẽ trả về giá trị false, ngược lại sẽ trả về giá trị true. Trong trường hợp giá trị của ModelState là false, thì action sẽ trả về view cũ và hiển thị những lỗi bất hợp lệ do người dùng nhập, như hình dưới đây:
Bạn thấy nội dung lỗi được hiển thị với màu đỏ ở hình trên, đó là kết quả do phương thức
Html.ValidationMessageFor trả về.