VieTopikKhoá học
  • Games
  • Cá nhân
Tải app
© 2026 VieTopikChính sách bảo mậtĐiều khoản sử dụngCài appEnglish
  • Trang chủ
  • Học
  • Luyện thi
  • Cẩm nang
  • Games
  • Cá nhân
ASP.NET Core Web APIXây API CRUD
Bài 5/19
5 phút

Trả về kết quả

Bình luận
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

Ở bài Controller và routing, gọi API lấy sản phẩm không tồn tại thì nhận về 204 thay vì 404. Client không phân biệt được "không có" với "thành công". Bài này chỉ cách chọn đúng status code cho từng trường hợp.

Khái niệm

📬 ActionResult: kiểu trả về của action, là dữ liệu kiểu T hoặc một kết quả kèm status code như 404.

Các method có sẵn trong ControllerBase để tạo kết quả:

Method Status code Khi nào dùng
Ok(data) 200 đọc thành công, có dữ liệu
CreatedAtAction(...) 201 tạo mới thành công
NoContent() 204 thành công, không có gì trả về
BadRequest() 400 dữ liệu gửi lên sai
NotFound() 404 không tìm thấy

Ví dụ

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
    private static readonly List<Product> Products =
        new List<Product>();

    [HttpGet("{id}")]
    public ActionResult<Product> GetById(int id)
    {
        var product =
            Products.FirstOrDefault(p => p.Id == id);
        if (product == null)
        {
            return NotFound();
        }
        return Ok(product);
    }

    [HttpPost]
    public ActionResult<Product> Create(Product product)
    {
        product.Id = Products.Count + 1;
        Products.Add(product);
        return CreatedAtAction(
            nameof(GetById),
            new { id = product.Id },
            product);
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public decimal Price { get; set; }
}
  • ActionResult<Product> cho phép trả NotFound() ở nhánh này và Ok(product) ở nhánh kia.
  • CreatedAtAction trả 201, kèm header Location chỉ tới URL của sản phẩm vừa tạo, ví dụ /api/products/1.
  • nameof(GetById) chỉ ra action dùng để dựng URL đó. Viết bằng nameof thì khi đổi tên method, compiler báo lỗi ngay.
  • new { id = product.Id } tạo nhanh một object không cần khai báo class, dùng để điền {id} vào URL.

Thử ngay

Chạy server. Tạo file product.json có nội dung { "name": "Pen", "price": 5000 }, rồi gọi:

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

Đoán trước khi chạy: lần gọi POST trả về status code nào, và lần gọi cuối còn là 204 không?

Xem kết quả
HTTP/1.1 201 Created
Location: http://localhost:5000/api/products/1
{"id":1,"name":"Pen","price":5000}

HTTP/1.1 200 OK
{"id":1,"name":"Pen","price":5000}

HTTP/1.1 404 Not Found

POST trả 201 kèm Location. Sản phẩm 99 giờ trả 404, vì action chủ động gọi NotFound() thay vì trả null.

Lỗi hay gặp

Trả null khi không tìm thấy. Client nhận 204, tưởng là thành công.

// SAI — không tìm thấy mà vẫn là "thành công"
using Microsoft.AspNetCore.Mvc;

public class OrdersController : ControllerBase
{
    [HttpGet("{id}")]
    public string? GetById(int id)
    {
        return null;
    }
}
// ĐÚNG
using Microsoft.AspNetCore.Mvc;

public class OrdersController : ControllerBase
{
    [HttpGet("{id}")]
    public ActionResult<string> GetById(int id)
    {
        return NotFound();
    }
}

Tạo mới mà trả 200. Tạo thành công nên trả 201 qua CreatedAtAction, để client biết ngay URL của thứ vừa tạo.

Tóm tắt

  • Dùng ActionResult<T> để một action trả được cả dữ liệu lẫn lỗi.
  • Đọc được thì Ok, tạo mới thì CreatedAtAction, không có thì NotFound.
  • Không trả null khi không tìm thấy, vì client sẽ nhận 204.
  • Status code đúng giúp client xử lý mà không phải đọc body.
Nhận dữ liệu từ requestDTO

Bình luận

Đang tải bình luận…

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