C# cơ bản .NET Core

Để 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()
{
}

Đăng ký nhận bài viết mới