VieTopik
Tiếng HànTiếng AnhIT
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
ASP.NET Core Web APIXây API CRUD
Bài 4/19
5 phút

Nhận dữ liệu từ request

Nội dung bài · 5 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt

API cần biết client muốn gì: sản phẩm số mấy, tìm theo tên nào, tạo sản phẩm với tên và giá bao nhiêu. Dữ liệu đó nằm ở ba chỗ trong request. Bài này chỉ cách nhận cả ba vào tham số của action.

Khái niệm

🔗 Model binding: cơ chế ASP.NET Core tự lấy dữ liệu trong request và gán vào tham số của action.

Nguồn Ví dụ trong request Attribute
Route /api/products/5 [FromRoute]
Query string ?name=pen&maxPrice=10000 [FromQuery]
Body (JSON) { "name": "Pen", "price": 5000 } [FromBody]

Với [ApiController], bạn thường không cần ghi attribute. Tham số có tên trong route lấy từ route, kiểu đơn giản như int, string lấy từ query, còn object lấy từ body.

Ví dụ

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
    [HttpGet("{id}")]
    public string GetById(int id) => $"Sản phẩm {id}";

    [HttpGet("search")]
    public string Search(
        string name, decimal maxPrice) =>
        $"Tìm {name}, giá tối đa {maxPrice}";

    [HttpPost]
    public Product Create(Product product) => product;
}

public class Product
{
    public string Name { get; set; } = "";
    public decimal Price { get; set; }
}
  • GetById(int id): id có trong route {id} nên lấy từ URL.
  • Search(string name, decimal maxPrice): không có trong route nên lấy từ query string ?name=...&maxPrice=....
  • Create(Product product): Product là object nên lấy từ body JSON.
  • ASP.NET Core tự đổi chữ trong URL thành int, decimal. Đổi không được thì trả lỗi 400.

Thử ngay

Chạy server, rồi gọi hai request GET:

curl -i "http://localhost:5000/api/products/5"
curl -i "http://localhost:5000/api/products/search?name=pen&maxPrice=10000"

Để gửi POST, tạo file product.json:

{ "name": "Pen", "price": 5000 }

Rồi gửi file đó làm body:

curl -i -X POST http://localhost:5000/api/products -H "Content-Type: application/json" -d @product.json

Đoán trước khi chạy: JSON gửi lên viết name chữ thường, còn property trong C# là Name. Action có nhận được tên sản phẩm không?

Xem kết quả
HTTP/1.1 200 OK
{"name":"Pen","price":5000}

Có. ASP.NET Core không phân biệt hoa thường khi đọc JSON vào object, nên name vẫn gán được vào Name. Action trả lại đúng object vừa nhận.

Lỗi hay gặp

Gửi chữ vào tham số số. id là int mà URL lại là chữ, model binding không đổi được và trả về 400.

// SAI — "abc" không phải số, nhận về 400 Bad Request
GET /api/products/abc
// ĐÚNG
GET /api/products/5

Quên header Content-Type. Không có -H, curl gửi body với kiểu của form (application/x-www-form-urlencoded). Server không đọc kiểu này như JSON và trả về 415 Unsupported Media Type.

# SAI — thiếu -H "Content-Type: application/json"
curl -i -X POST http://localhost:5000/api/products -d @product.json
# ĐÚNG
curl -i -X POST http://localhost:5000/api/products -H "Content-Type: application/json" -d @product.json

Tóm tắt

  • Model binding tự gán dữ liệu request vào tham số của action.
  • Dữ liệu đến từ route ({id}), query string (?name=) hoặc body JSON.
  • Với [ApiController]: tên trong route thì lấy từ route, kiểu đơn giản lấy từ query, object lấy từ body.
  • Gửi JSON phải có header Content-Type: application/json.

Tự kiểm tra

0/3 câu
Câu 1

Action [HttpGet("{orderId}/lines")] GetLines(int orderId, int page). Gọi GET /api/orders/7/lines?page=2 thì orderId và page bằng bao nhiêu?

Câu 2

Client gửi thông tin đơn hàng mới gồm nhiều trường. Dữ liệu này nên đặt ở đâu trong request?

Câu 3

POST body JSON đúng, nhưng server trả 415 Unsupported Media Type. Nguyên nhân khả dĩ nhất?

Controller và routingTrả về kết quả

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt