ASP.NET MVC WEB
Đây là một mô hình lập trình web mà được ông lớn microsoft tích hợp vào ASP để viết Web mô hình MVC và nó có tên là ASP.NET MVC.
Bài viết này là phần tổng hợp cũng như là những kinh nghiệm đúc kết mà mình học từ series ASP.NET MVC của trang dammio.com.
Contents
1. Giới thiệu ASP.NET MVC
ASP.NET MVC là 1 phần mềm mã mở, tách rời với thành phần độc quyền ASP.NET Web Forms.
3 vai trò: Model, View và Controller:
- Model (tầng business – business layer)
- View (tầng hiển thị – display layer)
- Controller (điều khiển đầu vào – input control)
Một số phiên bản đáng chú ý như MVC4, MVC5, MVC6 và phiên bản mới nhất là ASP.NET Core MVC 2.0.0, phát hành ngày 14 tháng 8 năm 2017.
=> Chúng ta sẽ tiếp cận MVC5
Link bài viết: [ASP.NET MVC] Phần 1: Giới thiệu ASP.NET MVC
2. Tạo website ASP.NET MVC đầu tiên
Tạo ứng dụng đầu tiên
Bạn mở VS 2013, chọn File -> New -> Project, một cửa sổ New Project sẽ hiện lên. Trong cửa sổ này, phần bên trái, bạn chọn Visual C#, phần bên phải chọn ASP.NET Web Application, đặt tên dự án.
Tiếp theo chọn dự án là kiểu MVC và nhấn OK.
Bạn được kết quả giao diện ban đầu khi khởi chạy ứng dụng.
Trong ứng dụng mặc định, bạn có 3 trang chính Home, About và Contact. Ứng dụng mặc định cũng dùng giao diện Bootstrap.
Bạn mở Solution Explorer (View -> Solution Explorer hoặc phím tắt Ctrl + Alt + L) để xem cấu trúc thư mục web.
Trong hình trên, một số giải thích cơ bản về cấu trúc thư mục, tập tin là:
- References: là nơi lưu trữ, thêm/bớt các thư viện DLL có liên quan đến website.
- App_Data: là nơi chứa cơ sở dữ liệu dạng tập tin .MDF, để làm dự án thuận tiện bạn nên chọn làm cơ sở dữ liệu dạng này.
- App_Start: chứa các lớp cấu hình sẽ kích hoạt chạy trước khi dự án web chạy.
- Content: chứa các tập tin nội dung như css, image, … bạn có thể thay đổi tập tin này nếu muốn.
- Controllers: nơi chứa các lớp điều khiển cho dự án
- Models: nơi chứa mô hình
- fonts, Script: chứa dạng font và mã JavaScript, phần này giúp xây dựng giao diện website, bạn có thể thay đổi tùy ý.
- Views: chứa các .cshtml để hiển thị giao diện
- Web.config: chứa cấu hình web, rất quan trọng
- Global.asax: chứa lớp cấu hình Session, Cookies, Application cho dự án
Link bài viết: [ASP.NET MVC] Phần 2: Tạo website ASP.NET MVC đầu tiên
3. Thêm mới Controller (điều khiển)
3.1 Tạo Controller
Tạo một controller mới:
Ở cửa sổ Solution Explorer, chuột phải lên thư mục Controllers => Add => Controller.
Ở hộp thoại Add Scaffold, chọn MVC 5 Controller – Empty => Add.
Sau đó, đặt tên Controller.
Lưu ý: bạn nên để tiền tố “Controller” cuối cùng khi đặt tên để dễ phân biệt lớp code nào là Controller.
3.2 Route – đường dẫn URL
ASP.NET MVC sẽ gọi các lớp controller khác nhau (kèm theo các phương thức) tùy theo URL đầu vào. Mặc định URL có định dạng:
…/[Controller]/[ActionName]/[Parameters] // ...: địa chỉ website // Controller: là tên phần đầu của Controller // ActionName: là tên phương thức // Parameters: là các tham số đầu vào của các phương thức
Lấy một ví dụ: Bạn có phương thức chào mừng trong DammioController
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace DammioMVC.Controllers { public class DammioController : Controller { // // GET: /Dammio/ChaoMung/ public string ChaoMung(string ten, int tuoi = 1) { return HttpUtility.HtmlEncode("Xin chào " + ten + ". Tuổi của bạn là: " + tuoi); } } } // -----------------Routing cho phương thức ChaoMung-----------------// // http://localhost:3456/Dammio/ChaoMung?ten=Dammio&tuoi=20
3.2.1 Thay đổi cấu hình url
Bạn có thể vào tập tin App_Start/RouteConfig.cs và chỉnh cấu trúc đường dẫn. Ví dụ chỉnh cấu trúc đường dẫn thành {action}/{controller}/{id}. Bạn hãy thay đổi mục url
namespace test { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); //routes.MapRoute( // name: "Default", // url: "{controller}/{action}/{id}", // defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } //); routes.MapRoute( name: "Default", url: "{action}/{controller}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } }
3.2.2 Thay đổi url chuẩn SEO không có ? cho tham số
Bạn sẽ thêm cấu hình cho Controller như sau vào App_Start/RouteConfig.cs (chèn sau định nghĩa route mặc định)
routes.MapRoute( name: "Dammio", url: "{controller}/{action}/{ten}/{tuoi}" );
Code đầy đủ của App_Start/RouteConfig.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace DammioMVC { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( name: "Dammio", url: "{controller}/{action}/{ten}/{tuoi}" ); } } }
Lúc này đường dẫn Route sẽ thay đổi như sau:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace DammioMVC.Controllers { public class DammioController : Controller { // // GET: /Dammio/ChaoMung/ public string ChaoMung(string ten, int tuoi = 1) { return HttpUtility.HtmlEncode("Xin chào " + ten + ". Tuổi của bạn là: " + tuoi); } } } // -----------------Routing cho phương thức ChaoMung-----------------// // http://localhost:3456/Dammio/ChaoMung/Dammio/0
Link bài viết: [ASP.NET MVC] Phần 3: Thêm mới Controller (điều khiển)
3.3 Tạo Controller với entityFramework
Bạn xem mục số 7 nhé!
4. Thêm mới View
4.1 Lưu ý về view
- Các file view sẽ nằm ở thư mục Views của dự án
- Các thư mục dưới thư mục Views sẽ là tên các controller tương ứng. Do đó tên thư mục phải giống tên Controller.
- Các file xxx.cshtml đại diện cho một phương thức của controller tương ứng. Do đó tên file cũng phải giống tên phương thức của controller đó.
4.2 Tạo view mới
Để tạo một View mới, bạn chọn thư mục Views/xxx trong Solution Explorers (xxx là tên thư mục controller tương ứng cần tạo view), sau đó chuột phải chọn Add -> MVC5 View Page with Layout (Razor).
Lưu ý, bạn phải thêm View tương ứng với Controller. Ví dụ, bạn có Controller tên là ABCController, thì lúc thêm View bạn phải thêm vào thư mục Views/ABC.
Sau đó, bạn phải đặt tên View vào hộp thoại, ví dụ Index và nhấn OK.
Tiếp theo, bạn chọn Layout (bố cục) cho View. Khi tạo dự án MVC thì Visual Studio để tạo cho bạn View mặc định là _Layout.cshtml, bạn có thể tạo bất cứ layout nào nếu muốn.
Sau khi bạn tạo xong, một tập tin Index.cshtml sẽ được tạo trong thư mục Views/Dammio vói nội dung mã nguồn như sau.
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }
4.3 Quy trình hiển thị view
Đầu tiên, một người dùng sẽ chạy đường dẫn http://localhost:xxxx/Dammio/Index, server sẽ dò tìm và biết được đường dẫn này thuộc về tập tin DammioController.cs với phương thức Index(). Tiếp tục, server sẽ thực thi nội dung trong phương thức Index() và trả về dòng lệnh return View(). Vì đây là phương thức Index trả về View, server sẽ dò tìm đúng tập tin có tên Index.cshtml nằm trong thư mục Views/Dammio. Tiếp theo, server đọc nội dung Index.cshtml và hiển thị mã HTML trên màn hình.
4.4 Thay đổi bố cục Layout và tập tin view
Bạn mở tập tin bố cục _Layout.cshtml ở thư mục /Views/Shared trong cửa sổ Solution Explorer:
- @RenderBody(): Các trang kế thừa sẽ khác nhau tại chỗ này còn lại giống nhau. (Khu vực thay đổi nội dung của các trang kế thừa)
- ActionLink (một siêu liên kết, giống như thẻ a href) như sau:
ActionLink(string linkText, string actionName, string controllerName) //linkText: là văn bản hiển thị trên đường dẫn //actionName: là tên phương thức //controllerName: là tên controller //------------Cách dùng------------// @Html.ActionLink("Liên kết", "Hello","Dammio") //nó sẽ chuyển mã HTML như sau: <a href="/Dammio/Hello">Liên kết</a>
4.5 Chuyển dữ liệu Controller sang View
Sử dụng biến ViewBag – là 1 thuộc tính động (dynamic), nó lưu trữ tất cả biến cần đẩy về. Ngoài ra, bạn còn có thể dùng ViewData (kiểu từ điện đối tượng) và TempData.
Ở Controller
public ActionResult Hello(string name, int numTimes = 1) { ViewBag.Message = "Hello " + name; ViewBag.NumTimes = numTimes; return View(); }
Ở View
@{ Layout = "~/Views/Shared/_Layout.cshtml"; } @{ ViewBag.Title = "Hello"; } <h3>Đây là nội dung của tập tin Hello.cshtml được xử lý từ phương thức Hello ở controller Dammio (DammioController).</h3> <ul> @for (int i = 0; i < ViewBag.NumTimes; i++) { <li>@ViewBag.Message</li> } </ul>
Link bài viết: [ASP.NET MVC] Phần 4: Thêm mới View
5. Thêm Model (mô hình)
5.1 EntityFramework và các kiểu tạo model
Khi lập trình ASP.NET, có lẽ bạn bắt buộc làm quen với công nghệ truy cập dữ liệu .NET Framework, hay còn gọi là Entity Framework (EF). Theo đó, EF sẽ tự động gieo Model cho ứng dụng ASP.NET MVC theo nhiều cách khác nhau như Code First, Database First và Model First.
- CodeFirst (viết code tay sau đó phát sinh dữ liệu database sau)
- DatabaseFirst (dựa vào database sẵn có để tạo tự động có mô hình mã nguồn)
- ModelFirst (xây dựng mô hình trên tập tin sơ đồ trước, sau đó tự động phát sinh mã nguồn và database sau).
5.2 Thêm model
Mình sẽ tạo theo DatabaseFirst.
Bạn lưu ý rằng bạn phải có cơ sở dữ liệu trước nhé.
Trong cửa sổ Solution Explorer, chuột phải lên thư mục Model, chọn Add -> New Item.
Tiếp đến, bên cột trái chọn Data và khung chính bên phải chọn ADO.NET Entity Data Model, và đặt tên mô hình Model.edmx (thay đổi cho phù hợp).
Tiếp theo, bạn chọn Generate from database.
Tiếp theo, trong cửa sổ kết nối tới Database, chọn nút New Connection… và đợi một chút cửa sổ Choose Data Source hiện ra, bạn chọn Microsoft SQL Server (Client). Sau đó, chọn server và cơ sở dữ liệu bạn muốn gieo mã nguồn.
Tiếp theo, bạn chọn tên chuỗi kết nối (ConnectionString) trong Web.Config tên là DammioMVCEntities(thay đổi cho phù hợp) và nhấn Next.
Tiếp theo, bạn chọn bảng để gieo mã nguồn như hình. Cuối cùng, nhấn Finish để Entity Framework gieo mô hình mã nguồn vậy là xong.
Sau khi EF gieo xong mã nguồn mô hình, bạn mở Model ra xem thấy cấu trúc thư mục đã hiện các lớp mã nguồn mới như sau.
5.3 Cập nhật model khi thay đổi cấu trúc database
Chọn tập tin Models/Model.edmx, sau đó mở tập tin này ra bạn thấy sơ đồ cấu trúc các bảng như sau.
Chọn chuột lên vùng trống ở giao diện mô hình khi mở tập tin Model.edmx, chọn chuột phải, chọn Update model from Database…
Sau đó, bạn chọn chế độ Refresh dành cho các bảng đã thêm vào mô hình hoặc Add dành cho các bảng mới. Sau khi thao tác xong thì chọn Finish.
5.4 Cập nhật model bị lỗi
Trong trường hợp có lỗi phát sinh mà bạn không thể sửa được, cách tốt nhất là xóa toàn bộ nội dung trong thư mục Models và gieo lại mô hình.
Link bài viết: [ASP.NET MVC] Phần 5: Thêm Model (mô hình)
6. Chuỗi kết nối
Mở tập tin Web.config:
- DefaultConnection chính là dạng kết nối tới SQL Server Express Database Engine (cơ chế dữ liệu nhanh của SQL Server) cho phép chạy ở chế độ người dùng và làm việc với các tập tin *.mdf.
- DammioMVCEntities(tùy bạn đặt tên lúc tạo). Đây chính là chuỗi kết nối mà dự án Web hiểu được database từ SQL Server theo kiểu MVC.
<add name="DammioMVCEntities" connectionString="metadata=res://*/Models.Model.csdl|res://*/Models.Model.ssdl|res://*/Models.Model.msl; provider=System.Data.SqlClient; provider connection string=" data source=(local); initial catalog=DammioMVC; integrated security=True; MultipleActiveResultSets=True; App=EntityFramework"" providerName="System.Data.EntityClient" />
- Ba tập tin Models.Model.csdl, Models.Model.ssdl và Models.Model.msl là các tập tin cấu hình MVC.
- data source=(local))
- tên database là initial catalog=DammioMVC
- chế độ tích hợp bảo mật (integrated security=True), không cần tài khoản đăng nhập.
Khi đưa lên server có IP database là 192.168.1.1 và có tài khoản đăng nhập User là “user” và Pass là “pass” thì bạn thay đổi chuỗi kết nối như sau:
<add name="DammioMVCEntities" connectionString="metadata=res://*/Models.Model.csdl|res://*/Models.Model.ssdl|res://*/Models.Model.msl; provider=System.Data.SqlClient; provider connection string=" data source=192.168.1.1, 1433; initial catalog=DammioMVC; User ID=user; Password=pass; Integrated Security=False; MultipleActiveResultSets=True; App=EntityFramework"" providerName="System.Data.EntityClient" />
Link bài viết: [ASP.NET MVC] Phần 6: Tìm hiểu về các chuỗi kết nối cơ sở dữ liệu (connection strings)
7. Truy cập mô hình dữ liệu từ Controller
Tạo Controler (Tạo xong nó sẽ tự tạo view cho mình luôn)
Ở Solution Explorer, chuột phải chọn thư mục Controllers, và nhấn Add, sau đó chọn Controller.
Ở hộp thoại Add Scaffold, chọn mục MVC 5 Controller with views, using EntityFramework và nhấn Add.
Sau đó, đối với tên Controller, bạn đặt tên của Controller (nhớ là tên + Controller nhé). Chọn Link (DammioMVC.Models) (Chọn tên bảng của bạn) tại Model class và chọn DammioMVCEntities (DammioMVC.Models) (tên lúc tạo model) cho Data context class. Bạn có thể dùng Layout mặc định nếu muốn (~/Views/Shared/_Layout.cshtml). Tiếp theo, nhấn Add, Visual Studio sẽ tạo các tập tin và thư mục.
Sau đó, hãy đợi một chút, Visual Studio sẽ tự động tạo mã nguồn tập tin LinkController.cs trong thư mục Controllers và tạo thư mục Views/Link chứa các tập tin Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml, và Index.cshtml. Bạn có thể bật cửa sổ Solution Explorer (Ctrl + Alt + L) để xem tổng quan các tập tin mới tạo.
Visual Studio sẽ tự động tạo các phương thức CRUD (create, read, update, và delete) và kèm theo giao diện (views) vì vậy với ASP.NET MVC, bạn có thể thực hiện làm giao diện trang Admin rất nhanh.
Mình thật sự bất ngờ khi làm tới đây. Mọi thứ được tạo sẵn từ create, update, delete, hiển thị danh sách, hiển thị một record. Trời ơi, mọi lần làm php, laravel đồ cực khổ lắm mới làm được mấy này, còn bây giờ Visual Studio làm tất. Nhưng nhược điểm làm phải quay lại tìm hiểu nó viết thế nào ^_^.
Link bài viết: [ASP.NET MVC] Phần 7: Truy cập mô hình dữ liệu từ Controller
8. Tìm hiểu về các phương thức Edit và View Edit
namespace DammioMVC.Models { using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; // thêm bằng tay public partial class Link { public int LinkID { get; set; } [Display(Name = "Tên liên kết")] // thêm bằng tay public string LinkName { get; set; } public string LinkURL { get; set; } public string LinkDescription { get; set; } public Nullable<int> CategoryID { get; set; } } }
- Nhúng thư viện System.ComponentModel.DataAnnotations dùng để định nghĩa chú thích cho các trường thuộc tính, bao gồm định nghĩa lại tên hiển thị, kiểu dữ liệu, định dạng dữ liệu hiển thị.
- Ví dụ trên định nghĩa thuộc tính LinkName khi xuất trên màn hình sẽ là “Tên liên kết“.
Tập tin View/Link/Edit.cshtml
- @Html.AntiForgeryToken() gieo token (mã bảo mật) dùng để chống lừa đảo ở một form ẩn và token này phải khớp với phương thức Eidt trong Link controller.
- Thuộc tính ValidateAntiForgeryToken dùng để ngăn chặn một yêu câu lừa đảo và đi kèm với @Html.AntiForgeryToken() ở tập tin view Views\Link\Edit.cshtml
- @Html.LabelFor(model => model.LinkName, new { @class = “control-label col-md-2” }): dùng để hiển thị tên của các trường thuộc tính Link như LinkName, LinkURL và LinkDescription
- @Html.EditorFor(model => model.LinkDescription): dùng để gieo một phần tử input cho phép người dùng nhập liệu
- @Html.ValidationMessageFor(model => model.LinkName): hiển thị thông điệp kiểm chứng liên quan đến thuộc tính, chẳng hạn ở trường nhập liệu kiểu int mà bạn nhập một chuỗi “abc” thì hệ thống sẽ báo lỗi nhập sai dữ liệu.
- phần tử form, thuộc tính value có giá trị “NF2G………….” thì đây chính là giá trị token ẩn (tự động gieo mỗi lần duyệt Web) để bảo mật cho trang web
Quy trình xử lý edit: Thuộc tính ValidateAntiForgeryToken kiểm chứng token => lấy các giá trị cần post ở form => một đối tượng Link => đẩy các giá trị này vào và kiểm chứng dữ liệu bằng phương thức ModelState.IsValid => gửi đi đến server để cập nhật hay chỉnh sửa. Nếu dữ liệu đầu vào hợp lệ, dữ liệu sẽ lưu vào tập hợp Link của db (thể hiện DbContext). Dữ liệu Link được lưu vào database thông qua phương thức SaveChanges. Sau đó, đoạn mã sẽ quay về giao diện trang Index của lớp LinkController, nơi hiển thị tất cả các Link, bao gồm những thay đổi vừa xảy ra.
Globalize (Định dạng ngày tháng, tiền tệ): bạn xem trong bài viết dưới nhé.
Link bài viết: [ASP.NET MVC] Phần 8: Tìm hiểu về các phương thức Edit và View Edit
A. Kinh nghiệm
A.1 Lỗi Unable to update the EntitySet
Unable to update the EntitySet ‘Link’ because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
Bạn gặp lỗi này khi chưa set khóa chính cho bảng trong cơ sở dữ liệu.
Cách khắc phục: đặt khóa chính cho bảng và update lại model và nhớ build project lại nhé.