C# Cơ bản .NET Core §1) Cài đặt, chương trình C# đầu tiên §2) Biến, kiểu dữ liệu và nhập/xuất §3) Toán tử số học và gán §4) So sánh, logic và lệnh if, switch §5) Vòng lặp for, while §6) Phương thức - Method §7) Phương thức - Delegate §8) Lớp - Class §9) Kiểu vô danh và dynamic §10) Biểu thức lambda §11) Event §12) Hàm hủy - Quá tải toán tử - thành viên tĩnh - indexer §13) Lớp lồng nhau - namespace §14) null và nullable §15) Mảng §16) Chuỗi ký tự §17) Tính kế thừa §18) Tính đa hình - abstract - interface §19) Struct và Enum §20) Ngoại lệ Exeption §21) IDisposable - using §22) File cơ bản §23) FileStream §24) Generic §25) Collection - List §26) SortedList §27) Queue / Stack §28) Linkedlist §29) Dictionary - HashSet §30) Phương thức mở rộng §31) ObservableCollection §32) LINQ §33) (Multithreading) async - bất đồng bộ §34) Type §35) Attribute Annotation §36) DI Dependency Injection §37) (Multithreading) Parallel §38) (Networking) HttpClient §39) (Networking) HttpMessageHandler §40) (Networking) HttpListener §41) (Networking) Tcp TcpListenerr/TcpClient §42) (ADO.NET) SqlConnection §43) (ADO.NET) SqlCommand §44) (EF Core) Tổng quan §45) (EF Core) Tạo Model §46) (EF Core) Fluent API §47) (EF Core) Query §48) (EF Core) Scaffold §49) (EF Core) Migration §50) (ASP.NET CORE) Hello World! §51) (ASP.NET CORE) Middleware §52) (ASP.NET CORE) Map - Request - Response §53) (ASP.NET CORE) IServiceCollection - MapWhen §54) (ASP.NET CORE) Session - ISession §55) (ASP.NET CORE) Configuration §56) (ASP.NET CORE MVC) Controller - View

Tạo ứng dụng ASP.NET MVC đầu tiên

MVC đó là một mô hình lập trình, có gắng chia code thành 3 phần: model triển khai các mô hình dữ liệu, truy cập dữ liệu. view biểu diễn dữ liệu cho người dùng, controller nhận các yêu cầu browser gửi đến và trả về http response.

Trong NET Core 3.0 tạo ứng dụng MVC từ template bằng lệnh

dotnet new mvc

Hãy tạo ra một thư mục mẫu đặt tên là Mvc-v1, vào thư mục đó, rồi gõ lệnh trên để thực hành.

Dự án mẫu tạo ra là cấu trúc cơ bản cho ứng dụng ASP.NET CORE MVC. Trong tổ chức thư mục dự án thấy có:

  • Controllers : nơi chứa các lớp sẽ nhận yêu cầu gửi đến và trả về nội dung Http Response.
  • Models: nơi chứa các lớp cung cấp, xử lý dữ liệu
  • Views: chứa các file .cshtml để dựng HTML
  • wwwroot: chứa các file tĩnh (hình ảnh, js, css ...). Trong thư mục này đã copy sẵn thư viện CSS Bootstrap và JS JQuery

Kết quả chạy trang web như hình sau:

Route - Định tuyển trong ASP.NET MVC

Routing (định tuyển) là quá quá trình xử lý thông qua nó ứng dụng xác định được cần thi hành các phương thức nào cho mỗi URL gửi đến. ASP.NET Core sử dụng một middleware để ánh xạ các URL tương ứng với phương thức nào của ứng dụng. Cụ thể hơn, Route xác định được phương thức (action) trong Controller - qua đó nó chuyển các thông tin Request đến và thi hành.

Trong ASP.NET có có sử dụng 2 Middleware để ánh xạ URL vào Action (phương thức) của Controller, trong Configure của lớp StartUp thể hiện như:

MapControllerRoute

/...
    app.UseRouting();


    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
/...

Đoạn code trên đã tạo ra một Route ánh xạ URL vào Controller, đó là URL với cấu trúc {controller=Home}/{action=Index}/{id?} nghĩa URL phù hợp mẫu có ba phần /controller/action/id phần thứ nhất tương ứng với tên Controller (tên lớp trong thư mục Controllers), phần thứ 2 biến action - là Action trong Controller (tên phương thức), phần thứ 2 là một tham số tên biến id (tham số này có dấu ? có nghĩa là có thể có hoặc không - tùy chọn)

Như vậy nếu truy cập địa chỉ /Home/Index thì có nghĩa sẽ tham chiếu đến lớp HomeController, gọi đến action (phương thức) Index của nó.

Tất nhiên, sẽ thêm được nhiều endpoint ánh xạ URL, khi truy vấn đến nó so sánh từ trên xuống, gặp cái nào phù hợp sẽ chuyển thi hành controller/action tương ứng. Ví dụ:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
        name: "myroute",
        defaults: new {controller="Home", action = "Index"},
        pattern: "{title}-{id}.html");
});

Ở Route tên myroute phù hợp khi truy cập URL dạng /tieude-134.html, ROUTE này không chỉ rõ Controller, Action trong pattern mà chỉ ra trong defaults như trên.

Tạo ràng buộc trong Route - URL

Với mỗi biến trong Route (như controller, action, id, title ...) có thể khống chế phải phù hợp với điều kiện nào đó, thường những điều kiện là biểu thức chính quy (RegEx - xem biểu thức chính quy). Ví dụ như Route có tên myroute sau đây:

/..
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
        name: "myroute",                                                     // đặt tên route
        defaults: new {controller="Home", action = "Index"},
        constraints: new {
            id     = @"\d+",                                                 // id phải có và phải là số
            title  = new RegexRouteConstraint(new Regex(@"^[a-z0-9-]*$"))    // title chỉ chứa số, chữ thường và ký hiệu -
        },
        pattern: "{title}-{id}.html");
});
/..

Tạo Controller trong ASP.NET MVC

Controller có chức năng nhận Request gửi đến và trả về Response. ASP.NET MVC thì các Controller lưu trong thư mục Controllers, đồng thời các lớp controller đặt tên có hậu tố là Controller, ví dụ *Controller, như trong ứng dụng đã tạo ra có sẵn lớp HomeController

Thông thường các controller kế thừa từ lớp Controller, sau đó khai báo các phương thức có thể được gọi khi Route ánh xạ đến gọi là Action

public class HomeController : Controller
{
    /...
    public IActionResult Index()
    {
        return View();
    }
    /...
}

Các Action

Controller có các phương thức gọi là Action, như trên action Index nó trả về IActionResult, thực tế nó có thể trả về bất kỳ kiểu dữ liệu nào. Ví dụ:

/...
public string XinChao() => "Xin chào ASP.NET Core 3.0";
/...

Truy cập địa chỉ /Home/XinChao thấy dòng text trên.

Phương thức Content trả về về nội dung + kiểu tài liệu

Phương thức Content của Controller, giúp trả về tài liệu với kiểu và nội dung.

/...
public IActionResult GetContent()
{
   string contentType =  "text/plain";                   // mime - tham khảo https://en.wikipedia.org/wiki/Media_type
   string content = "Đây là nội dung file văn bản";
   return Content(content, contentType, Encoding.UTF8);  //Content(content, contentType);  - có thể bỏ Endcoding
}
/...

Phương thức Json trả về Json từ đối tượng

Phương thức Json trích xuất các thuộc tính của đối tượng và chuyển thành Json, Response trả về có header Content-Type application/json

/...
public IActionResult GetJson()
{
    return Json(
        new {
            key1 = 100,
            key2 = new string[] {"a", "b",  "c"}
        }
    );
}
/...

Truy cập địa chỉ /Home/GetJson kết quả

{"key1":100,"key2":["a","b","c"]}

Chuyển hướng truy cập

Có một số phương thức để chuyển hướng, thường có tiền tố Redirect, ví dụ vài phương thức như:

public IActionResult TestRedirect()
{
    return Redirect("https://xuanthulab.net");                             // Redirect 302 - chuyển hướng sang URL khác
    // return RedirectToRoute(new {controller="Home", action="Index"});    // Redirect 302 - Found
    // return RedirectPermanent("https://xuanthulab.net");                 // Redirect 301 - chuyển hướng URL khác
    // return RedirectToAction("Index");                                   // Chuyển hướng sang Action khác
}

Trả về nội dung file

Phương thức File, tùy ngữ cảnh nó trả về nội dung file.

/...
public IActionResult FileAnh()
{
    string filepath = "logo.png";
    return File(filepath, "image/png");
}
/...

Trả về 404 - NotFound

/...
public IActionResult KhongCoGi()
{
    return NotFound(
        "Trang không thấy"
    );
}
/...

Sử dụng tham số cho Action

Có thể khai báo các Action có tham số, các tham số này được truyền thiết lập qua biến trong Route hay trong Url Query

/...
public IActionResult Sum(int x,  int y)
{
    return Content((x+y).ToString(), "text/plain", Encoding.UTF8);
}
/...

Truy cập /Home/Sum?x=10&y=100 trả về nội dung 110

Trong lớp Controller còn có các thuộc tính truy cập nhiều loại thông tin rất đa dạng, những thuộc tính này sẽ tìm hiểu dần ở các phần sau như:

  • HttpContext - thuộc tính này giúp lấy được ServiceProvider của ứng dụng.
  • Request
  • Response
  • RouteData - dữ liệu Route
  • ViewBagViewData - giúp chuyển dữ liệu đến View
  • TempData - giúp chia sẻ dữ liệu giữa các phiên
  • User

Tạo View trong ASP.NET MVC

View kết hợp với dữ liệu nó nhận được, phát sinh nội dung HTML trả về cho client. Các View được bố trí trong thư mục Views, nó là các template - là các file có phần mở rộng .cshtml, trong đó nó chứa mã HTML, đồng thời nhúng mã C# (server side script), những đoạn nhúng mã server side thì bắt đầu bằng ký hiệu @

Khi một Action trả về đối tượng ViewResult (phương thức View của Controller tạo ra loại đối tượng này). Thì nó sẽ sử dụng View .cshtml để tạo nội dung HTML. Nó sẽ tìm đến thư mục Views, tìm đến thư mục cùng tên Controller ví dụ Home, sau đó là file .cshtml cùng tên với Action - file .cshtml tìm được sẽ sinh HTML.

Nếu vậy:

public class HomeController : Controller
{
    /...
    public IActionResult Index()
    {
        return View(); // Trả về ViewResult
    }
    /...
}

Action trên sẽ sử dụng View tương ứng là Views/Home/Index.cshtml

@{
    Layout = null;
}
<!doctype html>
<html>
    <head>
        <title>Trang View đầu tiên</title>
    </head>
    <body>
        <p>View .CSHTML là template <strong>Razor</strong> - nó chứa code C# bắt đầu bởi @@</p>
        <p><i>@DateTime.Now.ToLongDateString()</i></p>
    </body>
</html>

Để chèn một dòng code server side, thì sử dụng @ sau đó là dòng code, Razor tự nhận biết được đoạn kết thúc hết code khi phát hiện thẻ HTML, như ví dụ trên

<p><i>@DateTime.Now.ToLongDateString() xuanthulab.net</i></p>

Để mở khối thì sử dụng thêm { ... }

@{
    //code C#
}

Truyền dữ liệu Controller tới View với ViewBag

Để truyền dữ liệu, trong Controller có thể sử dụng thuộc tính ViewBag, đây là kiểu Dictionary, có thể thiết lập dữ liệu vào nó với cặp key/value

public IActionResult Index()
{
    ViewBag.dulieu1 = "Đây là dữ liệu 1";   //key=dulieu1,  value = "Đây là dữ liệu 1"
    ViewBag.dulieu2 = 12345;
    return View();
}

Khi controller thiết lập dữ liệu qua ViewBag, thì ở View truy cập được bằng đúng tên này

@ViewBag.key
@{
    Layout = null;
}
<!doctype html>
<html>
    <head>
        <title>Trang View đầu tiên</title>
    </head>
    <body>
        <p>View .CSHTML là template <strong>Razor</strong> - nó chứa code C# bắt đầu bởi @@</p>
        <p><i>@DateTime.Now.ToLongDateString()</i></p>
        <p>@ViewBag.dulieu1</p>
        <p>@ViewBag.dulieu2</p>
    </body>
</html>

Truyền dữ liệu Controller tới View với Model

Có thể truyền tải một đối tượng từ Controller đến View, bằng cách tạo ra đối tượng đó ví dụ obj, rồi tạo với View(obj);

Ví dụ:

public IActionResult Index()
{
    ViewBag.dulieu1 = "Đây là dữ liệu 1";
    ViewBag.dulieu2 = 12345;

    List<string> sanpham = new List<string>()
    {
        "Bàn ăn",
        "Giường ngủ",
        "Tủ áo"
    };

    return View(sanpham);  //ViewResult trả về kèm đối tượng dữ liệu.
}

Lúc này ở View có thể truy cập được nó thông qua biến Model, nhưng ở phần đầu cần khai báo kiểu Model này với @model List<string>

@model List<string>
    
@{
    Layout = null;      
}
<!doctype html>
<html>
    <head>
        <title>Trang View đầu tiên</title>
    </head>
    <body>
        <p>View .CSHTML là template <strong>Razor</strong> - nó chứa code C# bắt đầu bởi @@</p>
        <p><i>@DateTime.Now.ToLongDateString() xuanthulab.net</i></p>
        <p>@ViewBag.dulieu1</p>
        <p>@ViewBag.dulieu2</p>

        <ol>
            @foreach (var sp in Model) {
                <li>@sp</li>
            }
        </ol>

    </body>
</html>

Ở phần tiếp theo sẽ trình bày về Layout

Source Code
Đăng ký theo dõi ủng hộ kênh