1. Trang chủ
  2. » Giáo Dục - Đào Tạo

11 chuong 11 tủ tài liệu bách khoa

28 62 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 28
Dung lượng 1,15 MB

Nội dung

CHAPTER11 SportsStore:Administration SportStore: Quản trị Trong chương tiếp tục xây dựng ứng dụng SportStore thêm tính quản trị cho phép quản lý danh mục sản phẩm (product catalog) Chúng ta thêm tính hỗ trợ thêm sửa xóa sản phẩm cho phép upload hình ảnh xuất sản phẩm danh mục Adding CatalogManagement (Thêm tính quản lý danh mục) Quy ước cho quản lý item biểu diễn đến user với kiểu trang: list page edit page hình 11-1 Figure 11-1.Sketch of a CRUD UI for the productcatalog Kết hợp với nhau, trang cho phép người dùng tạo, xem update item collection.Một cách tổng hợp, hoạt động gọi CRUD Những người phát triển cần thực CRUD thương xuyên nên VS cố gắng giúp họ cách phát sinh controllers có action method cho hoạt động CRUD view template để hỗ trợ Nhưng VS template , nghĩ tốt nên học cách sử dụng tính MVC Framework cách trực tiếp Creating a CRUDController (Tạo CRUD controller) Tôi tạo controller cho tính quản trị SportStore.Chuột phải vào Controllers folder SportStore.WebUI project Solution Explorer chọn Add>Controller pop-up menu.Chọn MVC Controller – Empty danh sách lựa chọn Nhấn Add, đặt tên AdminController nhấn Add để tạo file Controller/AdminController.cs Sửa nội dung class controller cho giống với list 11-1 Listing 11-1 The Contents of the AdminController.cs File usingSystem.Web.Mvc; using SportsStore.Domain.Abstract; namespace SportsStore.WebUI.Controllers{ public class AdminController : Controller { private IProductRepositoryrepository; public AdminController(IProductRepository repo) { repository =repo; } public ViewResult Index(){ returnView(repository.Products); } } } Cấu trúc controller khai báo dependency với IProductRepository interface, Ninject giải instance tạo, Controller định nghĩa action method, Index, gọi đến View method để chọn view mặc định cho hoạt động, truyền sản phẩm vào sở liệu view model UNIT TEST: THE INDEXACTION Hành vi quan tâm hàm Index Admin controller trả xác Product object vùng lưu trữ Chúng ta kiểm thử điều cách tạo vùng lưu trữ giả thực thi so sánh liệu kiểm thử so sánh với liệu trả vởi action method Sau unit test, tơi đặt vào file unit test gọi AdminTests.cs SportStore.UnitTest project using Microsoft.VisualStudio.TestTools.UnitTesting; usingMoq; using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; using SportsStore.WebUI.Controllers; usingSystem; using System.Collections.Generic; usingSystem.Linq; usingSystem.Web.Mvc; namespace SportsStore.UnitTests { [TestClass] public class AdminTests{ [TestMethod] publicvoid Index_Contains_All_Products(){ // Arrange - create the mock repository Mockmock = new Mock(); mock.Setup(m =>m.Products).Returns(new Product[]{ newProduct {ProductID = 1, Name = "P1"}, new Product {ProductID = 2, Name = "P2"}, new Product {ProductID = 3, Name ="P3"}, }); // Arrange - create acontroller AdminController target = newAdminController(mock.Object); //Action Product[] result =((IEnumerable)target.Index() ViewData.Model).ToArray(); //Assert Assert.AreEqual(result.Length, 3); Assert.AreEqual("P1", result[0].Name); Assert.AreEqual("P2", result[1].Name); Assert.AreEqual("P3",result[2].Name); } } } Creating a NewLayout (Tạo layout mới) Chúng ta tạo layout để dùng cho view chức quản trị SportStort Đây layout đơn giản cung cấp nơi đặt thay đổi vào view quản trị Tạo layout cách chuột phải vào Views/Shared folder SportsStore.WebUI project chọn Add> MVC Layout Page(Razor) pop-up menu Đặt tên _AdminLayout.cshtml (đừng quên gạch chân) nhấn nút OK để tạo file Views/Shared/_AdminLayout.cshtml Chỉnh lại nội dung file cho khớp với List 11-2 Chú ý: Như tơi giải thích từ trước, quy ước tên layout bắt đầu với dấu gạch (_) Razor dùng công nghệ Microsoft khác tên WebMatrix, vốn dùng dấu gạch để ngăn trang layout chuyển đến browser MVC khơng vần nảo vệ quy ước đặt tên chuyển lên ứng dụng MVC Listing 11-2 The Contents of the _AdminLayout.cshtml File @{ Layout =null; } @RenderBody() Chúng ta thêm lời gọi đến hàm RenderBody, nên nội dung view mà dùng layout dùng để chèn vào phần phản hồi đến server.(chúng ta không cần phải làm dùng tùy chọn Add>New Item dùng Visual Studio layout template, tắt cách tạo view cách trực tiếp, nghĩa cần chỉnh lại file tạo để có nội dung tơi cần) Chúng ta thêm link elements cho Bootstrap file cho CSS file chứa thông tin style, tạo để làm bật lỗi xác nhận đến người dùng Thực thi List View Bây có layout mới, thêm view vào project cho Index action method Admin controller Ngay tơi khơng phải fan tính dựng khung (scaffold) template có sẵn Visual Studio, tơi tạo view cho hàm Index dùng hệ thống scaffolding để thấy cách hoạt động Chỉ khơng thích đoạn code cắt sẵn, khơng có nghĩa khơng nên sử dụng Chuột phải vào folder Views/Admin project SportStore.WebUI chọ,n Add>View menu Đặt tên view Index, chọn List mục Template (đây mục thường đặt mục Empty), chọn Product Model Class, check chọn vào nút dùng layout page, chọn file _AdminLayout.cshtml Views/Shared folder Theo dõi cấu hình 11-2 Figure 11-2.Configuring a scaffoldview Chú ý: dùng tính List scaffold, VS giả định làm việc dãy IENumerable model view type nên chọn dạng đơn form class list Note When using the List scaffold, Visual Studio assumes you are working with an IEnumerable sequence of the model view type, so you can just select the singular form of the class from the list Nhấn nút Add để tạo view mới, nội dung giống List 11-3 (Tơi định mạng lại markup để khơng chiếm nhiều diện tích trang ) Listing 11-3 The Contents of the Views/Admin/Index.cshtml File @modelIEnumerable @{ ViewBag.Title ="Index"; Layout ="∼/Views/Shared/_AdminLayout.cshtml"; } Index

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

@Html.DisplayNameFor(model @Html.DisplayNameFor(model @Html.DisplayNameFor(model @Html.DisplayNameFor(model =>model.Name) =>model.Description) =>model.Price) =>model.Category) @foreach (var item in Model){ @Html.DisplayFor(modelItem =>item.Name) @Html.DisplayFor(modelItem =>item.Description) @Html.DisplayFor(modelItem =>item.Price) @Html.DisplayFor(modelItem =>item.Category) @Html.ActionLink("Edit", "Edit", new { id=item.ProductID })| @Html.ActionLink("Details", "Details", new {id=item.ProductID })| @Html.ActionLink("Delete", "Delete", new { id=item.ProductID }) } VS tìm kiểu đối tượng view model phát sinh element bảng liên quan đến thuộc tính định nghĩa kiểu model Chúng ta thấy cách mà view dựng nên cách chạy ứng dụng điều hướng cho đến /Admin/Index Hình 11-3 miêu tả kết Figure 11-3 Rendering the scaffold Listview Scafold view cố gắng tạo cấu hình hợp lý dựa sở view Chúng ta có cột cho thuộc tính lớp Product nối đến tác vụ CRUD dẫn đến action method Admin controller (tuy nhiên, từ lúc tạo controller khơng sử dụng tính scafolding nên action method khơng tồn ) Tính Scafolding khéo léo view phát sinh đơn giản bình thương khơng đáng có với project có độ phức tạp Lời khuyên nên bắt đầu với controller rỗng (empty controller), views layout thêm tính cần vào cần thiết Trở với hướng tiếp cận tự thực hành, thay đổi file Index.cshtml List 11-4 Listing 11-4.Modifying the Index.cshtmlView @modelIEnumerable @{ ViewBag.Title = "Admin: AllProducts"; Layout ="∼/Views/Shared/_AdminLayout.cshtml"; } AllProducts ID Name Price Actions @foreach (var item in Model){ @item.ProductID @Html.ActionLink(item.Name, "Edit", new { item.ProductID}) @item.Price.ToString("c") @using (Html.BeginForm("Delete", "Admin")){ @Html.Hidden("ProductID",item.ProductID) } } @Html.ActionLink("Add a new product", "Create", null, new { @class = "btn btn-default"}) View thể thông tin form chắn hơn, bỏ qua số thuộc tính lớp Product dùng Boostrap để đặt thơng số style Chúng ta xem cách view dựng lên hình 11-4 Figure 11-4 Rendering the modified Indexview Bây có trang danh sách ổn.Quản trị viên thấy product catalog có nút để thêm xóa kiểm tra thơng tin Trong phần thêm chức để hỗ trợ cho hoạt động Now I have a nice list page The administrator can see the products in the catalog and there are links or buttons to add, delete, and inspect items In the following sections, I will add the functionality to support each of these actions Sửa thông tin Products Để cung cấp tính tạo sửa , thêm trang cho phép sửa thông tin tương tự hình 11 -1 Cơng việc chia thành hai phần Hiển thị trang cho phép người quản trị thay đổi giá trị thuộc tính product Thêm action method xử lý thay đổi chúng submit (gửi đi) Tạo Edit action method List 11-5 nội dung Edit method thêm vào Admin controller Đây action method định lời lời gọi đến công cụ hỗ trợ Html.ActionLink torng Index view Listing 11-5.Adding the Edit Action Method in the AdminController.cs File usingSystem.Linq; usingSystem.Web.Mvc; usingSportsStore.Domain.Abstract; usingSportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { public class AdminController : Controller{ private IProductRepositoryrepository; public AdminController(IProductRepository repo) { repository =repo; } public ViewResult Index(){ returnView(repository.Products); } public ViewResult Edit(int productId) { Product product =repository.Products FirstOrDefault(p =>p.ProductID == productId); returnView(product); } } } Hàm đơn giản tìm product có ID tương ứng với tham số productId truyền đối tượng view model đến View method UNIT TEST: THE EDIT ACTIONMETHOD Tôi muốn kiểm thử hành vi Edit action method Trước tiên lấy sản phẩm mà yêu cầu cung cấp ID có tồn Rõ ràng muốn đảm bảo sửa product mà mong muốn Hành vi thứ hai không lấy sản phẩm u cầu ID khơng có vùng lưu trữ Sau hàm kiểm thử thêm vào file test AdminTest.cs [TestMethod] publicvoid Can_Edit_Product(){ // Arrange - create the mock repository Mockmock = new Mock(); mock.Setup(m =>m.Products).Returns(new Product[]{ newProduct {ProductID = 1, Name = "P1"}, new Product {ProductID = 2, Name = "P2"}, new Product {ProductID = 3, Name ="P3"}, }); // Arrange - create thecontroller AdminController target = newAdminController(mock.Object); //Act Product p1 = target.Edit(1).ViewData.Model as Product; Product p2 = target.Edit(2).ViewData.Model as Product; Product p3 = target.Edit(3).ViewData.Model asProduct; //Assert Assert.AreEqual(1, p1.ProductID); Assert.AreEqual(2, p2.ProductID); Assert.AreEqual(3,p3.ProductID); } [TestMethod] publicvoid Cannot_Edit_Nonexistent_Product(){ // Arrange - create the mock repository Mockmock = new Mock(); mock.Setup(m =>m.Products).Returns(new Product[]{ newProduct {ProductID = 1, Name = "P1"}, new Product {ProductID = 2, Name = "P2"}, new Product {ProductID = 3, Name ="P3"}, }); // Arrange - create thecontroller AdminController target = newAdminController(mock.Object); //Act Product result =(Product)target.Edit(4).ViewData.Model; // Assert Assert.IsNull(result); } Creating the EditView (Tạo Edit View) Bây có action method, tạo view để dựng nên Chuột phải vào folder Views/Admin Solution Explorer chọn Add>MVC5 View Page (Razor) phần menu Đặt tên thành Edit.cshtml, nhấn nút để tạo file thay đổi nội dung List 11-6 Listing 11-6 The Contents of the Edit cshtml File @modelSportsStore.Domain.Entities.Product @{ ViewBag.Title = "Admin: Edit " + @Model.Name; Layout ="∼/Views/Shared/_AdminLayout.cshtml"; } Edit@Model.Name @using (Html.BeginForm()){ @Html.EditorForModel() @Html.ActionLink("Cancel and return to List","Index") 10 Figure 11-7.Displaying the editor page forproducts Updating the ProductRepository Trước xử lý thay đổi, cần nâng cấp vùng lưu product cho phép khả lưu thay đổi Đầu tiên thêm method vào IProductRepository interfaces list 11-9 (để nhắc lại, thấy interface folder Abstract project SportStore.Domain) Before I can process edits, I need to enhance the product repository so that it is able to save changes First, I will add a new method to the IProductRepository interface, as shown in Listing 11-9 (As a reminder, you will find this interface in the Abstract folder of the SportsStore.Domain project.) Listing 11-9.Adding a Method to the IProductRespository.cs File using System.Collections.Generic; usingSportsStore.Domain.Entities; 14 namespace SportsStore.Domain.Abstract { public interface IProductRepository{ IEnumerable Products { get;} voidSaveProduct(Productproduct); } } Chúng ta sau thêm method vào việc thực thi Entity Framework vùng lưu trữ, định nghĩa Concrete/EFProductRepository.cs file List 11-10 Listing 11-10.Implementing the SaveProduct Method in the EFProductRepository.cs File using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; usingSystem.Collections.Generic; namespace SportsStore.Domain.Concrete{ public class EFProductRepository : IProductRepository { private EFDbContext context = newEFDbContext(); public IEnumerable Products { get { return context.Products;} } publicvoid SaveProduct(Product product){ if(product.ProductID == 0) { context.Products.Add(product); } else{ Product context.Products.Find(product.ProductID); if(dbEntry != null) { dbEntry.Name =product.Name; 15 dbEntry = dbEntry.Description = product.Description; dbEntry.Price = product.Price; dbEntry.Category =product.Category; } } context.SaveChanges(); } } } Việc thực thi hàm SaveChanges thêm product vào vùng nhớ ProductID 0, khơng áp dụng thay đổi vào vào entry tồn database Tôi không muốn sâu vào chi tiết Entity Framework giải thích từ trước, chủ đề riêng biệt khơng phần MVC Framework.Nhưng có vài điều hàm SaveMethod có mang theo thiết kế ứng dụng MVC Tôi biết cần thực thao tác update nhận tham số có ProductID khơng Tơi thực cách lấy đối tượng Product vùng nhớ với ProductID cập nhật thuộc tính cho chúng khớp với tham số đối tượng Tơi làm Entity Framework lần theo đối tượng tạo từ database Đối tượng truyền đến hàm SaveChanges tạo MVC Framework dùng công cụ model binder mặc định, nghãi Entity Framwork khơng biết đối tượng tham số không áp dụng thay đổi vào sở liệu Có nhiều cách đề giải vấn đề dùng cách đơn giản xác định vùng liên hệ với đối tượng cho phép Entity Framework biết cập nhật cách rõ ràng Hướng tiếp cận thay tạo model binder tùy chỉnh lấy đối tượng từ vùng chứa Đây nghe cách tiếp cận có nét sang trọng đòi hỏi thêm khả tìm kiếm vào interface vùng chứa cho phép chúng xác định đối tượng Product giá trị ProductID Handling Edit POSTRequests (Giải Edit POST Request) Ở thời điểm sẵn sàng thực thi nội dung truyền vào Edit action method Admin controller xử lý POST request quản trị viên nhấn vào nút Save Action method thể List 11-11 Listing 11-11.Adding the POST-Handling Edit Action Method in the AdminController.cs File using System.Linq; usingSystem.Web.Mvc; using SportsStore.Domain.Abstract; usingSportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { public class AdminController : Controller{ private IProductRepositoryrepository; public AdminController(IProductRepository repo) { repository =repo; } public ViewResult Index(){ returnView(repository.Products); } public ViewResult Edit(int productId) { Product product =repository.Products FirstOrDefault(p =>p.ProductID == productId); 16 returnView(product); } [HttpPost] public ActionResult Edit(Product product) { if (ModelState.IsValid){ repository.SaveProduct(product); TempData["message"] = string.Format("{0} has beensaved", product.Name); returnRedirectToAction("Index"); } else{ // there is something wrong with the data values returnView(product); } } } } Tôi kiểm tra model binder xác thực liệu chuyển đến user cách đọc giá trị thuộc tính ModelState.IsValid Nếu tất ổn, tơi lưu thay đổi vào vừng chứa gọi đến Index action method để trả danh sách sản phẩm Nếu có vấn đề với liệu, tơi dựng lại Edit view cho phép user chỉnh sửa lại cho xác Sau tơi lưu thay đổi vào vùng nhớ, lưu thông điệp cách dùng tính TempData Đây dictionary dàng key/value tương tự với sữ liệu session tính viewbag mà dùng trước Điểm khác chủ yếu session data so với temp data bị xóa kết thúc HTTP request Chúý tơi trả kiểu ActionResult từ hàm Edit Tôi dùng kiểu ViewResult ViewResult bắt nguồn từ ActionResult nóđược dùng muốn framework dừng view Tuy nhiên kiểu khác ActionResults khả dụng, số chúng trả hàm RedirectToAction, sẽđiều hướng lại browser để gọi đến Index action method Chúng ta sẽđề cập việc chương 17 Chúng ta sử dụng ViewBag trường hợp người dùng điều hướng lại ViewBag truyền liệu controller view khơng thể giữ liệu lâu HTTP request hành Tơi dùng tính session data sau thơng điệp vấn lưu giữ lại tơi xóa cách rõ ràng, tơi khơng muốn phải làm Vì tính TempDta hồn hảo cho việc đọc Chúng ta đọc liệu từ view dựng action method mà định hướng lại cho người dùng, định nghĩa phần UNIT TEST: EDITSUBMISSIONS Cho việc yêu cầu POST xử lý Edit action method, cần đảm bảo thay đổi hợp lệ đến đối tượng Product mà model binder tạo truyền đến vùng nhớ product để lưu Tôi muốn kiểm tra thay đổi không hợp lệ (khi mà lỗi model xẩy ra) không quyền vào vùng nhớ Sau hàm kiểm tra [TestMethod] publicvoid Can_Save_Valid_Changes(){ // Arrange - create mockrepository Mockmock = newMock(); // Arrange - create thecontroller AdminController target = newAdminController(mock.Object); // Arrange - create aproduct Product product = new Product {Name ="Test"}; // Act - try to save the product ActionResult result =target.Edit(product); // Assert - check that the repository was called mock.Verify(m =>m.SaveProduct(product)); 17 // Assert - check the method result type Assert.IsNotInstanceOfType(result,typeof(ViewResult)); } [TestMethod] publicvoid Cannot_Save_Invalid_Changes(){ // Arrange - create mockrepository Mockmock = newMock(); // Arrange - create thecontroller AdminController target = newAdminController(mock.Object); // Arrange - create aproduct Product product = new Product { Name= "Test"}; // Arrange - add an error to the model state target.ModelState.AddModelError("error","error"); // Act - try to save theproduct ActionResult result =target.Edit(product); // Assert - check that the repository was notcalled mock.Verify(m =>m.SaveProduct(It.IsAny()),Times.Never()); // Assert - check the method result type Assert.IsInstanceOfType(result,typeof(ViewResult)); } Hiển thị thông điệp xác nhận Tôi xử lý thông điệp lưu dùng TempData file laytout _AdminLayout.cshtml Bằng cách xữ lý thơng điệp template m tơi tạo thông điệp view dùnglayout mà không cần tạo thêm vùng Razor List 11-12 biểu diễn thay đổi file Listing 11-12.Handling the ViewBag Message in the _AdminLayout.cshtml File @{ Layout =null; } @if (TempData["message"] != null){ @TempData["message"] } @RenderBody() 18 Mẹo: lợi ích việc thao tác với thơng điệp template user thấy hiển thị trang dựng lên sau lưu thay đổi Ở thời điểm tại, trả chúng danh sách product, tơi thay đổi dòng công việc để dựng lên view khác user vấn thấy nội dung thông điệp (miễn view sử dụng layout đó) Giờ tơi có tất mảnh cần thiết để chỉnh sửa product.Để xem cách tất vận hành, chạy ứng dụng, điều hướng vào Admin/Index tạo vào thay đổi Chọn nút save Chúng ta quay lại list view thông điệp TempData hiển thị hình 11-8 Figure 11-8.Editing a product and seeing the TempDatamessage Thông điệp biến chúng chạy lại trang danh sách product TempData bị xóa nó đọc Việc tiện lợi khơng muốn thơng điệp cũ nằm lại 19 Thêm vào xác thực Model Trong trường hợp hầu hết project, cần thêm vào quy tác xác thực cho đối tượng model.Ở thời điểm tại, người quản trị điền giá tiền số âm bỏ trống phần mô tả, SportsStore vui vẻ chấp nhận điều lưu vào database Dù cho có hay ko liệu xấu lưu dựa vào việc có phù hợp với ràng buộc định nghĩa bảng dùng để tạo nên database chương List 11-13 cho thấy cách tơi áp dụng thích liệu vào lớp Product, cách làm lớp ShippingDetails chương trước Listing 11-13.Applying Validation Attributes to the Product.cs File using System.ComponentModel.DataAnnotations; usingSystem.Web.Mvc; namespace SportsStore.Domain.Entities { public class Product{ [HiddenInput(DisplayValue = false)] public int ProductID { get; set;} [Required(ErrorMessage = "Please enter a product name")] public string Name { get; set; } [DataType(DataType.MultilineText)] [Required(ErrorMessage = "Please enter adescription")] public string Description { get; set;} [Required] [Range(0.01, double.MaxValue, positiveprice")] public decimal Price { get; set;} ErrorMessage = "Please enter a [Required(ErrorMessage = "Please specify acategory")] public string Category { get; set;} } } Hàm hỗ trờ Html.TextBox Html.TextArea mà dùng view Edit.cshtml để tạo đầu vào element dùng MVC Framework để tín hiệu vấn đề khâu xác thực Những tín hiệu gửi cách dùng lớp định nghĩa file Content/ErrorStyle.css, có hiệu ứng làm bật vấn đề Tôi cần cung cấp cho người dùng nội dùng chi tiết vấn đề thấy List 11-14 Listing 11-14.Adding Validation Messages to the Edit.cshtml File @foreach (var property in ViewData.ModelMetadata.Properties) { if(property.PropertyName != "ProductID"){ @(property.DisplayName ?? property.PropertyName) @if (property.PropertyName == "Description"){ @Html.TextArea(property.PropertyName,null, new{ @class = "form-control", rows = 5}) 20 } else{ @Html.TextBox(property.PropertyName, null, new { @class = "form-control"}) } @Html.ValidationMessage(property.PropertyName) } } Trong chương 9, dùng hàm hỗ trợ Html.ValidationSumary để tạo danh sách hợp tất vấn đề form.Trong danh sách dùng hàm hỗ trợ Html.ValidationMessage, hiển thị thơng điệp cho thuộc tính model Chúng ta đặt hàm hỗ trợ Html.ValidationMessage đâu view quy ước (và nhạy cảm) nên đặt gần element có vấn đề xác thực nhẳm gửi đến user nội dung Trong hình 11-9 cho thấy cách thơng điệp xác thực xuất chỉnh sửa sản phẩm điền liệu không tuân theo quy tắc lớp Product Figure 11-9.Data validation when editingproducts 21 Enabling Client-SideValidation Bật chế xác thực bên phía Client Hiện tại, xác thực liệu áp dụng người quản trị gửi thay đổi đến server nhiều người dùng đòi hỏi phản hồi có vấn đề với liệu mà họ nhập vào Đó lý nhà phát triển thường muốn thực tji chế xác thực bên phía client Nơi mà liệu kiểm tra Browser , dùng Javascript MVC Framework thực thi xác thực bên phía server dựa thích liệu mà áp dụng lên lớp domain model Tính bật mặc định khơng hoạt động tơi không thêm đường dẫn đến thư viên Javascript MS cung cấp hỗ trợ cho phép xác thực bên phía client dùng thự viện jQuery lời gọi phổ biến từ jQuery plug-in, jQuery Validation MS mở rộng cơng cụ để thêm tính nang hỗ trợ xác thực cho thuộc tính Bước cài đặt gói xác thực Chọn Tools>Library Package Manager>Package Manager Console VS để mở hộp thoại Nuget command line điền vào lệnh sau Install-Package Microsoft.jQuery.Unobtrusive.Validation -version3.0.0 -projectnameSportsStore.WebUI Mẹo: đừng bận tâm bạn thấy thơng điệp nói gói cài đặt từ trước MS thêm gói cách thầm lặng vào project check vào Reference Script Libraries dùng tính Scafolding tạo view Tiếp theo cần thêm element để đưa Javascript file gói vào ứng dụng HTML Các đơn giản thêm đường dần _AdminLayout.cshtml file Do xác thực phía client làm việc trang dùng layout Chúng ta nhìn thấy thay đổi List 11-15 (thứ tự element quan trọng) Listing 11-15 Importing JavaScript Files for Client-Side Validation into the _AdminLayout.cshtml File @{ Layout =null; } @if (TempData["message"] != null){ @TempData["message"] } @RenderBody() Những bổ sung vào layout cho phép tính xác thực bên phía client hoạt động, cung cấp phản hồi đến người dùng giá trị họ điền vào trước họ gửi mẫu form Sự xuất thông báo lỗi đến người dùng tương lớp CSSđược dùng xác thực server dùng cho bên slient phản hồi không cần request phải gửi đến server Trong hầu hết trường hợp, xác thực phía client tính hữu dụng lí khơng muốn xác thực phía client, cần thêm câu lệnh vào view 22 @{ } ViewBag.Title = "Admin: Edit " + @Model.Name; Layout ="∼/Views/Shared/_AdminLayout.cshtml"; HtmlHelper.ClientValidationEnabled = false; HtmlHelper.UnobtrusiveJavaScriptEnabled =false; Những câu lệnh tắt tính xác thực bên phía client cho view thêm vào Chúng ta tắt xác thực phía client cho tồn ứng dụng cách đặt giá trị file Web.config sau Creating NewProducts (Tạo Product mới) Kế tiếp, thực thi Creat action method, xác định đường dẫn Add a new product danh sách prodct Việc cho phép người quản trị thêm item vào product catalog.Thêm khả tạo product cần thêm số thay đổi nhỏ vào ứng dụng.Đây ví dụ hữu ích cho thấy sức mạnh linh hoạt ứng dụng MVC thiết kế cấu trúc tốt Thêm hàm Creat vối nội dung List 11-16 vào Admin controller Listing 11-16.Adding the Create Action Method to the AdminController.cs File using System.Linq; usingSystem.Web.Mvc; using SportsStore.Domain.Abstract; usingSportsStore.Domain.Entities; namespace SportsStore.WebUI.Controllers { public class AdminController : Controller{ private IProductRepositoryrepository; public AdminController(IProductRepository repo) { repository =repo; } // other action methods omitted forbrevity public ViewResult Create(){ return View("Edit", newProduct()); } } 23 } Hàm Creat khơng tạo view mặc định cho Thay vào xác định Edit view nên dùng Điều hoàn toàn chấp nhận action method dùng view thường liên quan đến view khác Trong trường hợp này, truyền đối tượng product view model để Edit view đưa với trường rỗng Chú ý: Tôi chưa thêm unite test cho action method Làm kiểm tra khả MVC Framework để xử lý Viewseult ta trả kết action method vốn điều tơi chấp nhận ()Không thiết phải viết phần kiểm thử cho framework trừ nghi ngờ có xảy vấn đề với Điều dẫn đến việc chỉnh sửa Tơi thường trông đợi from gửi trả đến action dựng lên Html.BeginForm giả định theo mặc định phát sinh form HTML Tuy nhiên khơng hoạt động cho hàm Creat tơi muốn from gửi trả Edit action để tơi lưu liệu product Để xác định điều này, dùng phiên chứa tham số hàm hỗ trợ Html.BeginFrom để xác định mục tiêu from phát sinh Edit view Edit action method Admincontroller list 11-17, miêu tả thay đổi tạo cho file view Views/Admin/Edgit.cshtml Listing 11-17.Explicitly Specifying an Action Method and Controller for a Form in the Edit.cshtml File @modelSportsStore.Domain.Entities.Product @{ ViewBag.Title = "Admin: Edit " + @Model.Name; Layout ="∼/Views/Shared/_AdminLayout.cshtml"; } Edit@Model.Name @using (Html.BeginForm("Edit", "Admin")){ @foreach (var property in ViewData.ModelMetadata.Properties) { if(property.PropertyName != "ProductID"){ @(property.DisplayName ?? property.PropertyName) @if (property.PropertyName == "Description"){ @Html.TextArea(property.PropertyName,null, new{ @class = "form-control", rows = 5}) } else{ @Html.TextBox(property.PropertyName, null, new { @class = "form-control"}) } @Html.ValidationMessage(property.PropertyName) } } @Html.ActionLink("Cancel and return to List", "Index", null, new{ @class = "btnbtn-default" }) } 24 Giờ form gửi đến Edit action action dựng lên Giờ tạo product nhấn vào link Add a new product điền vào chi tiết hình 11-10 Figure 11-10.Adding a new product to thecatalog DeletingProducts (Xóa product) Thêm tính hỗ trợ cho phép xóa quan trọng Đầu tiên thêm vào hàm IProductRepository interface List 11-18 Listing 11-18.Adding a Method to Delete Products to the IProductRepository.cs File using System.Collections.Generic; usingSportsStore.Domain.Entities; namespace SportsStore.Domain.Abstract { public interface IProductRepository{ IEnumerable Products { get; } void SaveProduct(Productproduct); Product DeleteProduct(intproductID); } } 25 Tiếp theo thực thi hàm lớp vùng nhớ Entity Framework List 11-19 Listing 11-19.Implementing Deletion Support in the EFProductRepository.cs File using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities; usingSystem.Collections.Generic; namespace SportsStore.Domain.Concrete{ public class EFProductRepository : IProductRepository { private EFDbContext context = newEFDbContext(); public IEnumerable Products { get { return context.Products;} } publicvoid SaveProduct(Product product){ if(product.ProductID == 0) { context.Products.Add(product); } else{ Product dbEntry context.Products.Find(product.ProductID); if(dbEntry != null) { dbEntry.Name =product.Name; dbEntry.Description = product.Description; dbEntry.Price = product.Price; dbEntry.Category =product.Category; } } context.SaveChanges(); } public Product DeleteProduct(int productID){ Product dbEntry = context.Products.Find(productID); if (dbEntry != null){ context.Products.Remove(dbEntry); context.SaveChanges(); } returndbEntry; } } } Bước cuối thực thi Delete action method Admin controller Action method nên hỗ trợ POST request xóa đối tượng khơng phải phần tử thay đổi Tôi đề cập chương 16 Browser caches tự để gửi GET request mà không cần đến đồng ý rõ ràng từ user nên phải cẩn thận tạo thay đổi kết Get request List 11-20 biểu diễn action method Listing 11-20 The Delete Action Method in the AdminController.cs File using System.Linq; usingSystem.Web.Mvc; using SportsStore.Domain.Abstract; usingSportsStore.Domain.Entities; 26 = namespace SportsStore.WebUI.Controllers{ public class AdminController : Controller { private IProductRepositoryrepository; public AdminController(IProductRepository repo) { repository =repo; } // other action methods omitted forbrevity [HttpPost] public ActionResult Delete(int productId){ Product deletedProduct = repository.DeleteProduct(productId); if (deletedProduct != null){ TempData["message"] = string.Format("{0} was deleted", deletedProduct.Name); } returnRedirectToAction("Index"); } } } UNIT TEST: DELETINGPRODUCTS Tôi muốn kiểm thử hành vi Delete action method, mà ProductID có thực truyền vào tham số, action method gọi đến hàm DeleteProduct vùng nhớ truyền ProductID để xóa Sau tets [TestMethod] publicvoid Can_Delete_Valid_Products(){ // Arrange - create aProduct Product prod = new Product { ProductID= 2, Name = "Test"}; // Arrange - create the mock repository Mockmock = new Mock(); mock.Setup(m =>m.Products).Returns(new Product[]{ newProduct {ProductID = 1, Name = "P1"}, prod, newProduct {ProductID = 3, Name ="P3"}, }); // Arrange - create thecontroller AdminController target = newAdminController(mock.Object); // Act - delete the product target.Delete(prod.ProductID); // Assert - ensure that the repository delete methodwas // called with the correctProduct mock.Verify(m =>m.DeleteProduct(prod.ProductID)); } 27 Chúng ta thấy tính delete cách nhấn nút delete trang danh sách product hình 11-11 Như biểu diễn hình, tơi lợi dụng biến TempData để hiển thị product bị xóa khỏi catalog Figure 11-11.Deleting a product from thecatalog Tổng hợp Trong chương tơi giới thiệu tính quản trị vào cho thấy cách thực hoạt động CRUD cho phép người quản trị thêm, đọc, cập nhật xáo sản phẩm từ vừng nhớ Trong chương học cách để bảo mật tính quản trị khơng cho phép sử dụng tất user thên vào chút tính để hồn thiện ứng dụng SportsStore 300 ... Admin controller xử lý POST request quản trị viên nhấn vào nút Save Action method thể List 11- 11 Listing 11- 11.Adding the POST-Handling Edit Action Method in the AdminController.cs File using System.Linq;... nhấn nút delete trang danh sách product hình 11- 11 Như biểu diễn hình, tơi lợi dụng biến TempData để hiển thị product bị xóa khỏi catalog Figure 11- 11.Deleting a product from thecatalog Tổng hợp... nhẳm gửi đến user nội dung Trong hình 11- 9 cho thấy cách thơng điệp xác thực xuất chỉnh sửa sản phẩm điền liệu không tuân theo quy tắc lớp Product Figure 11- 9.Data validation when editingproducts

Ngày đăng: 09/11/2019, 07:19

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN