ASP.NET MVC so với Web Forms Smackdown (p.2)
_Bài viết này được viết khi ASP.NET MVC 2 đã ra khỏi dây chuyền lắp ráp. Kể từ đó MVC 3 (4) đã được phát hành. Một cải tiến là "application/json" kiểu MIME được hỗ trợ đầy đủ. Điều này có nghĩa rằng bạn có thể POST và trả về nội dung JSON. _ Code Samples Tôi đã tạo ra một ứng dụng Web ASP.NET ...
_Bài viết này được viết khi ASP.NET MVC 2 đã ra khỏi dây chuyền lắp ráp. Kể từ đó MVC 3 (4) đã được phát hành. Một cải tiến là "application/json" kiểu MIME được hỗ trợ đầy đủ. Điều này có nghĩa rằng bạn có thể POST và trả về nội dung JSON. _
Code Samples
Tôi đã tạo ra một ứng dụng Web ASP.NET mẫu gọi là Notepad, cho bài viết này. Nó thực hiện cả một phiên bản MVC và một phiên bản Web Forms của một lưu ý đơn giản dùng giao diện. Mỗi phiên bản thực hiện một mẫu POST đồng bộ để lấy Notes và một Form POST không đồng bộ để thêm ghi chú mới. Bằng cách đánh giá từng phiên bản của Notepad chúng ta có thể có được một ý tưởng tốt hơn về sự khác biệt giữa Web Forms và MVC ...
ASP.NET MVC Form POST
Thực hiện một POST Form trong ASP.NET MVC là điều ngạc nhiên đơn giản nếu bạn bỏ qua tất cả mọi thứ bạn đã học về ASP.NET Web Forms.
Các MVC Notepad có một Form để tìm kiếm tác giả. Submit Form thực hiện POST dữ liệu của mẫu đối với một URL. ASP.NET Routing đánh giá các URL và định tuyến các yêu cầu để điều khiển thích hợp. Controller nhận Notes mong muốn, liên kết chúng vào một View mới, và trả kết quả về các tài liệu HTML.
ASP.NET Routing có thể cấu hình. Đây là những gì cho "Tìm Kiếm Theo tác giả" Form trong MVC Notepad.
routes.MapRoute( "MvcGetNotesByAuthor", "Notepad/MvcGetNotesByAuthor", new { controller = "Notepad", action = "GetNotes" });
Global.asax.cs trong ScottsJewels.Samples.Notepad
Và đây là những gì "Tìm Kiếm Theo tác giả" Form trông như thế nào.
<form action="<%= ResolveUrl("~/Notepad/MvcGetNotesByAuthor") %>" method="post"> <div> <fieldset> <input type="text" id="searchAuthor" name="searchAuthor" /> <button type="submit" name="button" value="GetNotesByAuthor">Search Author</button> </fieldset> </div> </form>
/Views/Notepad/Notepad.aspx Trong ScottsJewels.Samples.Notepad Khi Form được submit, các mẫu được so sánh với các đường ánh xạ trong ASP.NET Routing. Trong trường hợp này hàm "GetNotes" được gọi vào "Notepad" Controller. Hơi gây nhầm lẫn với ASP.NET MVC ngụ ý rằng tên lớp cho các điều khiển là "NotebookController" (phần Controller được tacked về tự động). Hàm "GetNotes" được gọi là một ActionMethod. Đây là những gì "GetNotes" ActionMethod trông như thế nào.
[HttpPost] public ActionResult GetNotes(string button, string searchAuthor) { ActionResult result; switch (button) { case "GetNotesByAuthor": if (searchAuthor != null && !string.IsNullOrEmpty(searchAuthor.Trim())) { result = View("Notepad", NotepadDataAccess.GetInstance().GetNotesByAuthor(searchAuthor)); } else { result = View("Notepad", NotepadDataAccess.GetInstance().GetNotes()); } break; default: result = IndexNote(); break; } return result; }
/Controllers/NotepadController.cs Trong ScottsJewels.Samples.Notepad Các ActionMethod chấp nhận các param. Các param được ánh xạ tới yêu cầu bằng tên. Trong kịch bản này, các "nút" tham số sẽ chứa các giá trị của các nút HTML mà submit trên form.
Các ActionMethod cũng trả về một ActionResult. Có nhiều loại hình của ActionResults mà bạn có thể trả về từ một ActionMethod. Trong kịch bản này, chúng tôi đang trả về một ViewResult. Các liên kết với một ViewResult và View Model với nhau để tạo ra một tài liệu HTML. ViewResult binding một danh sách các "Note" Model cho "Notepad" View.
Các [HttpPost] "GetNotes" ActionMethod giới hạn yêu cầu HTTP POST. Nếu muốn bạn có thể hạn chế ActionMethod của bạn từ HTTP cụ thể như GET, PUT, DELETE và sử dụng các thuộc tính tương tự .
Đây là những gì mà mô "Note" trông như thế nào.
[Serializable] public class Note { [Required] [DisplayName("Author")] public string Author { get; set; } [Required] [DisplayName("Title")] public string Title { get; set; } [Required] [DisplayName("Text")] public string Text { get; set; } }
Note.cs trong ScottsJewels.Samples.Notepad.DataModels Và đây là những gì "Notepad" View như thế nào.
<%@ Page Title="My Notepad (MVC)" Language="C#" MasterPageFile="~/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<ScottsJewels.Samples.Notepad.DataModels.Note>>" %> <%@ Import Namespace="ScottsJewels" %> <%@ Import Namespace="ScottsJewels.Samples.Notepad.DataModels" %> ... <asp:Content ContentPlaceHolderID="bodyContent" runat="server"> ... <div id="notes"> <% if (Model != null && Model.Count > 0) { foreach (Note note in Model) { %> <div class="note"> <span><%=note.Title%> by <%=note.Author%></span> <p> <%=note.Text%> </p> </div> <% } } %> </div> </asp:Content>
/Views/Notepad/Notepad.aspx Trong ScottsJewels.Samples.Notepad Chú ý ở đầu trang quy định Model View có thể ràng buộc vào. View chỉ có thể được liên kết với một Model duy nhất. Đối với View phức tạp cần nhiều nguồn dữ liệu này có thể yêu cầu nhiều ViewModels được tạo ra. Ngoài ra, lưu ý rằng không có mã phía sau (.aspx.cs) cho một ASP.NET MVC View. Tất cả của logic diễn ra trong View Markup hoặc Controller. Khi View này tải nó sẽ hiển thị tất cả các đối tượng "Note" chứa trong nó bị ràng buộc bởi Model.
ASP.NET MVC Form POST sử dụng AJAX
Trong ASP.NET MVC có hai cách để xử lý một AJAX Form POST. Bạn có thể phơi bày một dịch vụ Web. Hoặc, bạn có thể tận dụng một ASP.NET MVC Controller. Một dịch vụ Web là quen thuộc hơn và cho phép bạn thiết lập một độc "dữ liệu tầng" (với một chút công việc ). Tuy nhiên, nếu bạn muốn tuân thủ thực hiện MVC của Microsoft có lẽ bạn nên sử dụng một bộ điều khiển. web serivce không phù hợp tốt vào các mô hình MVC. Ngoài ra, Webserivce không thể được chuyển đến bằng ASP.NET Routing và sẽ dẫn đến một tài nguyên Không tìm thấy (404).
Vì lợi ích của ví dụ này tôi sẽ thực hiện AJAX sử dụng ASP.NET MVC Controller.
Đây là những gì các "Add Note" Form trông như thế nào.
<form action="<%= ResolveUrl("~/Notepad/AddNote") %>" id="addNoteForm"> <div> <fieldset> <legend>Add Note</legend> <p> <label for="author">Author :</label> <input style="position:absolute; left: 120px;" type="text" id="Author" name="Author"/> </p> <p> <label for="title">Title :</label> <input style="position:absolute; left: 120px;" type="text" id="Title" name="Title"/> </p> <p> <label for="text">Text :</label> <input style="position:absolute; left: 120px;" type="text" id="Text" name="Text"/> </p> <p> <button type="submit" name="button" value="GetNotes">Add Note</button> </p> </fieldset> <div id="message"></div> </div> </form>
/Views/Notepad/Notepad.aspx Trọng ScottsJewels.Samples.Notepad Thoạt nhìn nó có vẻ giống như cách nhấn vào "Add Note" sẽ thực hiện một POST đồng bộ với máy chủ Web. Tuy nhiên, nếu bạn có một cái nhìn tại các client-side Javascript bạn sẽ thấy rằng Form submit đã được ghi đè. Thay vì thực hiện POST đồng bộ các form sẽ được submit đồng bộ bằng JQuery của .ajax().
$(document).ready(function () { $("#addNoteForm").link(jsonNote); $("#addNoteForm").submit(function (event) { // Stop form from submitting normally. event.preventDefault(); var $form = $(this); var $message = $("#message"); var url = $form.attr('action'); $('#addNoteForm').unlink(jsonNote); $.ajax({ type: 'POST', contentType: "application/x-www-form-urlencoded", data: jsonNote, url: url, success: function (data) { $form.link(jsonNote); if (data.IsSuccessful == true) { $message.text("Note added successfully!"); jsonNote.Author = ""; jsonNote.Text = ""; jsonNote.Title = ""; $form[0].reset(); } else { $message.text(data.ErrorMessage); } $message.fadeIn(500,function () { $message.fadeOut(2000); }); } }); }); });
/Scripts/Notepad.js Trong ScottsJewels.Samples.Notepad Các khối Javascript của các sự kiện submit và trích xuất thông tin của Form từ DOM HTML. Sau đó nó tổ chức một đại diện JSON của Model "Note" và gửi nó vào máy chủ Web. Vậy những "Note" đến từ đâu? Nó đã được trả lại cho View khi Javascript sau đây đã được xử lý bởi ASP.NET.
<script type="text/javascript" language ="javascript"> var jsonNote = <%= (new Note().ToJson() ) %> </script>
/Views/Notepad/Notepad.aspx Trong ScottsJewels.Samples.Notepad Đây là những gì Route cho "Add Note". Routing xử lý tất cả các yêu cầu như nhau bất kể họ là đồng bộ hoặc không đồng bộ.
routes.MapRoute( "AjaxAddNote", "Notepad/AddNote", new { controller = "Notepad", action = "AddNote" });
Global.asax.cs trong ScottsJewels.Samples.Notepad URL được yêu cầu bởi các "Add Note" Form được ánh xạ tới các "AddNote" ActionMethod vào "Notepad" Controller. Các "AddNote" ActionMethod hơi khác một chút so với cái được sử dụng trong ASP.NET MVC Form POST. Để bắt đầu nó trả về một JsonResult - không phải là một View. JsonResult chỉ là - một kết quả JSON, hoặc dữ liệu tinh khiết. Nó cũng chấp nhận một đối tượng "Note" như một tham số. Các tham số được gắn với yêu cầu tải với một chút giúp đỡ từ JQuery .
[HttpPost] public JsonResult AddNote(Note note) { JsonResult result = new JsonResult(); if ((!string.IsNullOrEmpty(note.Author)) && (!string.IsNullOrEmpty(note.Title)) && (!string.IsNullOrEmpty(note.Text))) { NotepadDataAccess.GetInstance().SubmitNote( new Note { Author = note.Author, Text = note.Text, Title = note.Title }); result.Data = new ClientResponse(true, true, string.Empty); } else { result.Data = new ClientResponse(false, false, "Author, Title, and Text must not be empty!"); } return result; }
/Controller/NotepadController.cs Trong ScottsJewels.Samples.Notepad Nguồn: http://scottsjewels.blogspot.com/