---
# System prepended metadata

title: 'Đề số 1: Kiểm tra C# - SQL - Javascript (AngularJS - JQUERY)'

---

# Đề số 1: Kiểm tra C# - SQL - Javascript (AngularJS - JQUERY)
1. Tạo dự án .NET MVC Core. Thực hiện viết Model cho bảng `KhachHang` bao gồm: 
 - `Id int primary key`
 - `HoTen string`
 - `NgayThangNamSinh DateTime`
 - `IdCanCuoc string`
 - `DiaChi string`
 - `ImgPathCCCD string`
2. Tạo Database cho dự án bằng Codefirst
3. Tạo View với địa chỉ `/Home/QuanLyCanCuoc` và viết View theo cấu trúc HTML như ảnh 
![anh-mau](https://cdn.anh.moe/c/pDMhQ.md.png)
4. Khi bấm vào nút UploadImage, cho phép người dùng tải lên hình ảnh CCCD và gọi vào action ở địa chỉ `/Home/ReadingOCR`
5. Viết action `ReadingOCR` trong controller `Home`, input đầu vào là ảnh được tải lên ở yêu cầu bên trên, thực hiện nghiệp vụ lưu ảnh vào thư mục `uploads` trong thư mục `wwwroot` của dự án **VÀ** gọi vào API tại fpt.ai với các thông tin sau:
 - `ApiUrl = "https://api.fpt.ai/vision/idr/vnm";`
 - `ApiKey = "OgjC5zaxxzQYOjyMPISY0CBT2zz1U0l8";`
 - Code mẫu: 
    ```c#
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.IO;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;

    namespace YourWebApp.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class FptApiController : ControllerBase
        {
            private const string ApiKey = "OgjC5zaxxzQYOjyMPISY0CBT2zz1U0l8";
            private const string ApiUrl = "https://api.fpt.ai/vision/idr/vnm";
            private readonly IWebHostEnvironment _hostingEnvironment;

            public FptApiController(IWebHostEnvironment hostingEnvironment)
            {
                _hostingEnvironment = hostingEnvironment;
            }

            [HttpPost]
            [Route("upload")]
            public async Task<IActionResult> UploadImage(IFormFile file)
            {
                if (file == null || file.Length == 0)
                {
                    return BadRequest("File không hợp lệ.");
                }

                // Lưu ảnh vào thư mục 'upload' trong 'wwwroot'
                var uploads = Path.Combine(_hostingEnvironment.WebRootPath, "upload");
                if (!Directory.Exists(uploads))
                {
                    Directory.CreateDirectory(uploads);
                }
                var filePath = Path.Combine(uploads, file.FileName);
                using (var fileStream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(fileStream);
                }

                using (var client = new HttpClient())
                using (var content = new MultipartFormDataContent())
                {
                    // Thêm api-key vào header
                    client.DefaultRequestHeaders.Add("api-key", ApiKey);

                    // Thêm ảnh vào content từ file đã lưu
                    var imageContent = new ByteArrayContent(System.IO.File.ReadAllBytes(filePath));
                    imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse(file.ContentType);
                    content.Add(imageContent, "image", file.FileName);

                    // Gửi yêu cầu POST
                    var response = await client.PostAsync(ApiUrl, content);

                    if (response.IsSuccessStatusCode)
                    {
                        var responseString = await response.Content.ReadAsStringAsync();
                        return Ok(responseString);
                    }
                    else
                    {
                        return BadRequest($"Lỗi: {response.StatusCode}");
                    }
                }
            }
        }
    }


    ```


6. Sau khi nhận response từ API, nếu không có lỗi gì thì tiến hành đọc thông tin từ response và lưu vào các thông tin tương ứng
 - Mẫu response thành công: 
 ```json
    {
    "errorCode" : 0,
    "errorMessage" : "",
    "data": [
        {
        "id": "xxxx",
        "id_prob": "xxxx",
        "name": "xxxx",
        "name_prob": "xxxx",
        "dob": "xxxx",
        "dob_prob": "xxxx",
        "sex": "N/A",
        "sex_prob": "N/A",
        "nationality": "N/A",
        "nationality_prob": "N/A",
        "home": "xxxx",
        "home_prob": "xxxx",
        "address": "xxxx",
        "address_prob": "xxxx",
        "address_entities": {
                "province": "xxxx",
                "district": "xxxx",
                "ward": "xxxx",
                "street": "xxxx"
        },
        "doe": "N/A",
        "doe_prob": "N/A",
        "type": "xxxx"
        }
    ]
    }
 ```
  - Response thành công sẽ lưu các dữ liệu tương ứng vào database, với các trường tương ứng và trường `ImgPathCCCD` là địa chỉ ảnh đã được lưu.

 7. Trên VIEW: 
 - Hiển thị toàn bộ các khách hàng đã được lưu trong database ra bảng với thông tin tương ứng. Yêu cầu phân trang với độ dài 1 trang có 5 dòng, yêu cầu tính toán số trang
 - Hiển thị tìm kiếm: Khi nhập tìm kiếm, nếu ấn nút Enter trên bàn phím thì sẽ lọc ra toàn bộ các khách hàng có thông tin tương ứng.
 - Hiển thị thống kê: Thống kê tổng số khách hàng, tổng số khách hàng ở Hà Nội, HCM và Đà Nẵng (Có thể nhập mẫu dữ liệu để tính toán)
 - Hiển thị được hình ảnh CCCD trên bảng
 - Yêu cầu bổ sung: Khi Import nếu thành công thì sẽ tự động nhảy thêm ra dòng dữ liệu mới, không tiến hành load lại trang
 - Sử dụng công nghệ AngularJS hoặc Jquery AJAX

