Thứ tư, ngày 7 tháng 12 năm 2016

Khám phá action Edit aspnet mvc

Ngày đăng: 9/10/2012, 14:49:25PM | Lượt xem: 4,441
Hot!

 Hôm nay 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
 
        public ActionResult Edit(int id)
        {
            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.

 

Ở trong mã bạn cũng có thể thấy các phương thức Html.ValidationMessageFor() hoặc 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" />

        <div class="editor-label">
            <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ề.

Hiệu chỉnh action Edit để xử lý lỗi không tìm thấy tác vụ

Phương thức Edit dành cho GET Request không có mã để kiểm tra lỗi không tìm thấy tác vụ, và điều đó có nghĩa là khi trình duyệt gởi request có tham số id không tồn tại và như vậy chúng ta đang cập nhật một tác vụ không có thật, và lúc đó kết quả sẽ trả về như sau:

Và nếu bạn nhập thông tin hợp lệ vào form và lưu kết quả thì sẽ bị báo lỗi do model không tồn tại:

Để làm cho action Edit có thể xử lý được tình huống nói trên, ta cần điều chỉnh đoạn mã bên trong nó để kiểm tra xem thử phương thức Find của đối tượng DbContext trả về kết quả null hay không, nếu có thì cần phải điều hướng đến một thông báo lỗi hợp lệ, hơn là trả về lỗi, và mã điều chỉnh sẽ như sau:

public ActionResult Edit(int id)
        {
            Task task = db.Tasks.Find(id);
            if(task == null)
            {
                return HttpNotFound();
            }
            return View(task);
        }

Khi gặp phải tình huống không tìm được tác vụ, action sẽ trả về kết quả là phương thức HttpNotFound, phương thức này sẽ trả về lỗi 404 cho trình duyệt. 

Khi lập trình với các HTTP Verbs (GET, POST, PUT, DELETE..) bạn cần phải chú ý để có các thao tác phù hợp và tránh gây ra các lỗi về bảo mật. Đối với GET request, bạn không nên thay đổi hoặc sửa xóa dữ liệu khi xử lý các GET request, bởi nó sẽ tạo ra lỗ hổng về bảo mật (chúng tôi sẽ sớm có bài viết về vấn đề này). Thay đỗi dữ liệu khi xử lý GET request cũng vi phạm các quy tắc lập trình với giao thức HTTP và vi phạm kiến trúc REST, trong đó nó quy định rằng các GET request không nên làm thay đổi trạng thái của ứng dụng. Nói một cách khác, phương thức xử lý GET request phải là một phương thức không tạo ra ảnh hưởng lề (side effects).

 

 

 

Nguồn d.jou.vn
 Chia sẻ qua: 
Hot!
Ý kiến bạn đọc

These items will be permanently deleted and cannot be recovered. Are you sure?

Gallery

image

Maecenas viverra rutrum pulvinar

Maecenas viverra rutrum pulvinar! Aenean vehicula nulla sit amet metus aliquam et malesuada risus aliquet. Vestibulum rhoncus, dolor sit amet venenatis porta, metus purus sagittis nisl, sodales volutpat elit lorem…

Read more

Text Links

Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
Copyright © 2011 - 2012 vietshare.vn by phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.