[ASP.NET] Có nên sử dụng trực tiếp model được sinh tự động?

Lý do viết bài này rất đơn giản: mình bỏ cả buổi chiều ngồi cố gắng return danh sách sản phẩm dạng JSON từ controller về mà toàn lỗi 500 Internal Server Error.

error-500

500 Internal Server Error

Đầu tiên đổ tại lỗi IIS Express, khởi động đi khởi động lại, build đi build lại mà vẫn lỗi :((. Search hoài cả buổi thì cuối cùng cũng tìm ra vấn đề là thằng model sinh tự động từ DB ra nó có kết nối khóa ngoại nên không Serialize về dạng JSON được (thảo nào toàn return 500 :(( ).  Cách fix là tạo ra 1 model khác (VD: ProductViewModel), coppy toàn bộ bên model sinh tự động sang trừ thằng nào có chữ “virual” ra (khóa ngoại).

Định note lại mà nhớ ra note xong không nhớ note để đâu cộng với blog để lâu không post bài nên quyết định viết 1 bài 😀

Đoạn dưới đây mình viết xàm thôi, nên đọc nửa chừng thấy củ chuối thì bỏ đi :v. Quan trọng biết cách fix là được.

Nói qua về vấn đề của mình, mình có 2 cái model sinh tự động từ DB ra trông như này

400

Code tự động generate từ ADO.NET Entity Model

Code model tự động sinh của nó trông như này

401.jpg

Code tự động sinh của class Product

Mình muốn gửi 1 request ajax đến lấy ra danh sách các sản phẩm.


var name = $('#searchInput1').val();
 $.ajax({
          contentType: "application/json",
          dataType: 'json',
           data: {'name': name},
 type: "GET",
 url: '/Home/SearchResult',
 success: function (response) {
console.log(response);
}
 });

Tay nhanh hơn não, mình liền viết ngay 1 phương thức bên trong HomeController:


// GET: Home/SearchResult/name
 [HttpGet]
 public JsonResult SearchResult(string name)
 {
 List<Product> list = db.Products.Where(x => x.ProductName.Contains(name)).ToList();
 return Json(list, JsonRequestBehavior.AllowGet);
 }

 

Không ngờ gặp lỗi

398

Lỗi 500 Internal Server Error khi gửi request

Nhanh tay, mình cắm ngay 2 con debug ở chỗ list và return, hòng chén ngay con bug này.

403.jpg

Cắm debug :v

Ơ, select ngon lành thế kia cơ mà, rõ ràng có 2 thằng product  trong list, thế mà nó trả về 500 to tướng.

404.jpg

Và mình khắc phục như sau:

Tạo class ProductViewModel


 public class ProductViewModel {
 public long ProductID { get; set; }
 public long CategoryID { get; set; }
 [Required(ErrorMessage = "Vui lòng nhập tên sản phẩm")]
 public string ProductName { get; set; }
 public string ProductDescription { get; set; }
 public string ProductNote { get; set; }
 }

Để ý thì thấy nó khác cái Product tự sinh ở chỗ bỏ hàm


public virtual Category Category { get; set; }

Đây là hàm kết nối đến bảng danh mục thông qua khóa ngoại CategoryID

Cuối cùng là sửa code trong HomeController


List<Product> list = 
 db.Products.Where(x => x.ProductName.Contains(name))
 .ToList();
 List<ProductViewModel> viewList = new List<ProductViewModel>();

foreach (var product in list)
 {
 viewList.Add(new ProductViewModel()
 {
 ProductID = product.ProductID,
 CategoryID = product.CategoryID,
 ProductName = product.ProductName,
 ProductDescription = product.ProductDescription,
 ProductNote = product.ProductNote
 });
 }

return Json(viewList, JsonRequestBehavior.AllowGet);

Ngoài ra, khi update CSDL, nếu sử dụng trực tiếp model sinh sẵn, có thể gây lỗi.
Nếu sử dụng model riêng, thì có thể dùng tạm mấy bữa rồi fix sau cũng được =)))

Kết luận

Tránh sử dụng model sinh tự động =))

Một suy nghĩ 3 thoughts on “[ASP.NET] Có nên sử dụng trực tiếp model được sinh tự động?

  1. Pingback: Khác nhau giữa Entity Model và Business Object (BO) | minhphong306

  2. I do кnow!? Mentioned Larry. ?I ɡuess he lіkes angels as a
    result of he has tһem around all the time. Perhaps he and the angels play
    household games like we do sometimes. Maybe they play Monopoly.?
    This made Mommy chuckle really hard.

    Thích

Bình luận về bài viết này