Để thực hành phần này hãy tạo ra một dự án MVC, tạo thư mục mvcblog
, vào thư mục đó gõ lệnh:
dotnet new mvc
Sau khi dự án MVC đơn giản trên được tạo ra, dùng Visual Studio Code mở ra để bắt đầu thực hành.
Việc phát sinh các Url, map Url vào các Razor Page, Controller ... có thể thiết lập vài thông số, thực hiện trong Startup.ConfigureServices
services.Configure<RouteOptions> (options => { options.AppendTrailingSlash = false; // Thêm dấu / vào cuối URL options.LowercaseUrls = true; // url chữ thường options.LowercaseQueryStrings = false; // không bắt query trong url phải in thường });
Các trang Razor Page cùng hoạt động song song với các Controller/View trong mô hình MVC, để kích hoạt route tới Razor Page thực hiện cấu hình như sau:
Thêm vào Startup.ConfigureServices
chức năng về Razor AddRazorPages
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); // Thêm vào các chức năng, dịch vụ về Razor Page services.AddRazorPages(); }
Trong Startup.Configure
cập nhật thêm Route đến Razor Page
app.UseEndpoints(endpoints => { // ... các endpoint khác của MVC // Thêm route đến Razor endpoints.MapRazorPages(); });
Tạo nhanh một Razor Page kiểm tra: Tạo razor page About
với namespace mvcblog.testrazor
, code sinh ra ở arear testrazor
thư mục Areas/testrazor/Pages
(xem Area với Razor Page)
dotnet new page -n About -na mvcblog.testrazor -o Areas/testrazor/Pages
Mở Areas/testrazor/Pages/About.cshtml
cập nhật thành
@page @model mvcblog.testrazor.AboutModel @{ Layout = "_Layout"; // Thiết lập Layout của trang (View/Shared/_Layout.cshtml) } <p class="alert alert-danger"> Đây là trang Razor trong MVC </p>
Truy cập: /testrazor/About
Như vậy route có thể điều hướng đến Razor Page hay Controller tùy thuộc vào cấu hình của bạn.
Bạn có thể tạo rẽ nhánh HTTP Request trong pipeline của ứng dụng, kỹ thuật này đã trình bày ở IApplicationBuilderMap
Ví dụ: trong Startup.Configure
cập nhật thêm
// Truy cập /testapi trả về Json app.Map("/testapi", app => { app.Run(async context => { context.Response.StatusCode = 500; context.Response.ContentType = "application/json"; var ob = new { url = context.Request.GetDisplayUrl(), content = "Trả về từ testapi" }; // Nhớ thêm package Newtonsoft.Json // dotnet add package Newtonsoft.Json string jsonString = JsonConvert.SerializeObject(ob); await context.Response.WriteAsync(jsonString, Encoding.UTF8); }); }); // điểm cuối pipleline khi không route được đến Page, Controller, Map nào app.Run (async (HttpContext context) => { context.Response.StatusCode = StatusCodes.Status404NotFound; await context.Response.WriteAsync ("Page not found!"); });
Khi tạo các Route đến các Controller như trình bày tại Tạo route , mỗi route bạn đặt một cái tên - tên này được sử dụng trong nhiều ngữ cảnh ví dụ chuyển hướng đến route, tạo Url từ route ...
Hãy tạo ra một Controller là LearnAsp nhanh như sau ( aspnetcodegenerator):
dotnet aspnet-codegenerator controller -name LearnAsp -outDir Controllers
Tạo View nhanh cho Action Index của nó
dotnet aspnet-codegenerator view Index Empty -outDir Views/LearnAsp -l _Layout -f
Mở file View vừa phát sinh ra thêm vào cuối dòng
<h1>Học Asp.net Core MVC</h1>
Tạo thêm một route đặt tên là learnasproute
- code trong Startup.Configure
endpoints.MapControllerRoute ( name: "learnasproute", // đặt tên route defaults : new { controller = "LearnAsp", action = "Index" }, pattern: "learn-asp-net/{id:int?}");
Giờ truy cập các Url như /learn-asp-net
, learn-asp-net/10
thì nó truy cập Action Index của Controller LearnAsp
Tên này có thể dùng để chuyển hướng, ví dụ trong Action nào đó của Controller
// Chuyển hướng đến: /learn-asp-net/100 return RedirectToRoute("learnasproute", new {id = 100});
Hoặc tạo Url từ Controller
var url = Url.RouteUrl("learnasproute", new {id = 100}); // url = /learn-asp-net/100
Trong View tạo các liên kết
<a asp-route="learnasproute" asp-route-id="1">Bài học 1</a>
Tên Route không được đặt là: action
, area
, controller
, handler
, page
Khi http request gửi đến ứng dụng (truy vấn) nó có thể thực hiện các phương thức như post
, get
, put
... Tương ứng ASP.NET có các thuộc tính để chỉ ra Action nào đó trong Controller chỉ làm việc trên Http method cụ thể, gồm:
Chúng đều có cách sử dụng giống nhau, ví dụ: Action sau chỉ cho truy cập bằng http post, nếu get bị cấm
[HttpPost] public IActionResult Index() { return View(); }
Các thuộc tính trên nó còn nhận tham số là chuỗi template
, nếu vậy nó sẽ tạo Route đến Action theo template. Trường hợp này nó thay thế Route đến Action khai báo trong Startup.configure
Ví dụ:
public class LearnAspController : Controller { [HttpGet("/hoc-lap-trinh-asp/{id:int?}/")] public IActionResult Index() { return View(); } }
Truy cập đến Index trên tương ứng với các Url - /hoc-lap-trinh-asp/
, /hoc-lap-trinh-asp/123
...
Trong View nếu viết:
<a asp-controller="LearnAsp" asp-action="Index" asp-route-id="123">Học Asp</a>
Thì HTML sinh ra là:
<a href="/hoc-lap-trinh-asp/123">Học Asp</a>
Route tạo ra như trên - nếu muốn đặt tên thì thiết lập thêm tham số Name, ví dụ đặt tên Route là routeabc
public class LearnAspController : Controller { [HttpGet("/hoc-lap-trinh-asp/{id:int?}/", Name = "routeabc")] public IActionResult Index() { return View(); } }
Sử dụng tương tự như các thuộc tính theo Http Method như [HttpGet]
, [HttpPost]
, [HttpPut]
...
Nó khởi tạo với tham số là template để tao route theo cú pháp: [Route("template")]
, nó cũng có thuộc thuộc tính Name để tạo tên route, có thêm thuộc tính Order để thiết lập thứ tự kiểm tra phù hợp Url. Khác với HttpMethodAttribute nó tác dụng lên cả phương thức (Action) và lớp (controller)
[Route("learnasp2020")] public class LearnAspController : Controller { [Route("bai-kiem-tra")] [Route("test/{id?}")] [Route("/kiem-tra-ngay")] public IActionResult Test() { return Content("Kiểm tra route"); } }
Với cách tạo Route trên, Test được gọi khi truy cập các Url như: /learnasp2020/bai-kiem-tra
,/learnasp2020/test
, /learnasp2020/test/123
... Bạn thấy Url được kết hợp giữa template khai báo ở lớp và template khai báo ở Action
Trong đó nếu template ở Action viết dạng tuyệt đối thì nó không kết hợp, ví dụ trênn là /kiem-tra-ngay
Bạn có thể sử dụng ký hiệu thay thế (token) trong template khi tạo route bằng thuộc tính [Route]
, [HttpGet]
, [HttpPost]
... Các ký hiệu thay thế này là:
[area]
tương ứng với tên Area của controller[controller]
tương ứng với tên controller[action]
tương ứng với tên Actionpublic class LearnAspController : Controller { [Route("abc-[controller]-xyz[action]")] // Url phù hợp = /abc-learnasp-xyztest public IActionResult Test() { return Content("Kiểm tra route"); } }
Mã nguồn tham khảo ASP_NET_CORE/mvcblog, hoặc tải về bản bài này ex068-v1
Bạn có thể chỉ định rõ một Action của Controller cấp nhận các Http Method nào (get, post, put, update ...) bằng cách sử dụng [AcceptVerbs]
khởi tạo bằng cách liệt kê các Method mà Action chấp nhận, ví dụ: Action sau chấp nhận truy vấn bằng phương thức GET, PUT, POST
[AcceptVerbs("GET", "POST", "PUT")] public IActionResult Test() { }
Nguồn tin: Xuanthulab