- Cấu hình chung cho Route
- Tích hợp Route cho Razor Page
- Route rẽ nhánh IApplicationBuilder.Map
- Đặt tên route trong MVC
- Route MVC theo HTTP Method
- Route MVC sử dụng thuộc tính [Route]
- Sử dụng ký hiệu thay thế trong [Route] và [HttpMethod]
- Sử dụng thuộc tính AcceptVerbs - chấp nhận các Http Method
Để 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.
Cấu hình chung cho Route
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 });
Tích hợp Route - Razor Page vào MVC
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.
Route rẽ nhánh IApplicationBuilder.Map
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!"); });
Đặt tên Route trong MVC
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
Route đến Action theo HTTP Method
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:
- [HttpGet]
- [HttpPost]
- [HttpPut]
- [HttpDelete]
- [HttpHead]
- [HttpPatch]
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(); } }
Route bằng cách sử dụng thuộc tính [Route]
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
Sử dụng token trong [Route] và [HttpMethod]
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 Action
public 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
Thuộc tính AcceptVerbs - Thiết lập chấp nhận các Http Method trên Action
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() { }