# Đề 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

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