- [VB.NET] Hướng dẫn giải captcha sử dụng dịch vụ AZCaptcha API trên winform
- [C#] Hướng dẫn chứng thực đăng nhập ứng dụng bằng vân tay (Finger Print) trên máy tính
- [C#] Color Thief cách xuất màu sắc thiết kế từ hình ảnh
- [C#] Cách tạo bản quyền và cho phép dùng thử ứng dụng Winform
- [C#] Hướng dẫn sử dụng trình duyệt web Chrome convert HTML sang tập tin file PDF
- [C#] Kết nôi điện thoại Android, IOS với App Winform via Bluetooth
- [DATABASE] Cách query cộng trừ dồn dần trong Sqlserver
- [C#] Thiết kế ứng dụng Console đẹp với thư viện Spectre.Console
- [C#] Thiết kế ứng dụng Single Instance và đưa ứng dụng lên trước nếu kiểm tra ứng dụng đang chạy
- [C#] Giới thiệu JSON Web Token và cách đọc chuỗi token
- [C#] Cách tăng giảm font chữ tất cả các control trên winform
- [DEVEXPRESS] Tích hợp chức năng Tìm kiếm Search vào CheckedComboboxEdit
- [C#] Gởi email Metting Calendar Reminder kèm nhắc thời gian lịch họp
- [C#] Tìm kiếm xem danh sách từ khóa có tồn tại trong đoạn văn bản hay không
- [C#] Thiết kế giao diện ứng dụng trên Console sử dụng thư viện Terminal.Gui
- [C#] Hướng dẫn tạo mã VietQR Payment API Winform
- [C#] Sử dụng thư viện BenchmarkDotNet đo hiệu năng của hảm Method
- [DEVEXPRESS] Tìm kiếm không dấu tô màu highlight có dấu trên C# Winform
- [C#] Chia sẻ source code tạo hiệu ứng pixel Image trên winform
- [C#] Hướng dẫn kiểm tra số Container hợp lệ hay không
[dotNet5.0] Web API - MSSQL Server - Dapper
Hế lồ mọi ngừi,
Covi thật sự không muốn rời xa, "theo tình tình chạy" còn Covi thì đuổi mãi không đi. Thời gian này khá là rảnh rỗi, nên hôm nay mình sẽ hướng dẫn các bạn tạo ra một Web API xịn xò con cò viết bằng ngôn ngữ Net Core phiên bản 5.0 nhé.
Ví dụ này khá là cơ bản, tuy nhiên cũng không kém phần chuyên nghiệp, cấu trúc rõ ràng, và các bạn hoàn toàn có thể sử dụng để làm nền tảng cho các dự án NetCore sử dụng SQL luôn.
Web API with DotNet 5.0 using MSSQL and Dapper - Github
LaptrinhVB hiện đã có khá nhiều bài viết về Dapper, có lẽ mọi người cũng không còn xa lạ gì nữa.
Trong bài viết này, mình đã vận dụng SQLHelper class của a Thảo Meo, đồng thời có một số chỉnh sửa nhất định cho phù hợp với dự án Net Core.
Nhắc cũng khá nhiều cụm từ NetCore rồi, vậy Vì sao lại sử dụng NetCore ?
- Bởi vì chúng ta có căn bản về C#, hầu hết hàm, lệnh trong NetFramework đều có thể sử dụng ở trong NetCore, đó là một lợi thế đối với các bạn đang theo học C#. Hơn nữa, với NetCore, bây giờ chúng ta có thể xây dựng ứng dụng webserver chạy trên các nền tảng khác chứ không còn bó buộc với Windows nữa v.v... Và cuối cùng là, chúng ta thích. :D
Để tìm hiểu kỹ hơn, các bạn Google hộ mình nhé.
Các bạn nên vào trang chủ của Microsoft để xem qua để có thể khái quát cách hoạt động của một API NetCore. Hiện tại, nhóm đã có đầu tư hơn về chi tiết của Netcore, sau đó hẵng quay lại bài này, vì bài này hơi 18+, và hơn hết là trang chủ không chỉ chúng ta xài Dapper đâu :3.
Bắt đầu nào:
Chúng ta cần phải cài dotnet để có thể code và chạy ứng dụng này. Cài SQL Server để có thể sử dụng database.
Đầu tiên là cấu trúc thư mục mình sẽ hướng đến: Controllers, Models, DTOs, Repositories, Settings and Helpers.
Tiếp theo: Mở Visual studio Code lên, Ctrl + ~ để mở Terminal và gõ câu lệnh để thử tạo 1 webapi cho mình để test:
dotnet new webapi -n <tên-ứng-dụng>
1. Nếu cài thành công, bạn hãy tải source (source ở cuối bài viết) của mình về, giải nén và mở ra bằng Visual studio Code. Sau đó cài sẵn các thư viện SQLClient và Dapper vào:
dotnet add package System.Data.SqlClient
dotnet add package Dapper
dotnet add package Dapper.Contrib
2. Như vậy là đầy đủ các thư viện cần thiết rồi, mở Microsoft SQL Server management Studio lên và excute tập tin này để tạo ra database cho ứng dụng (hoặc không cần thiết nếu bạn đã sẵn có database):
--Open this file in Microsoft SQL Server Management Studio
--And Press Excute button above
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'DEMO_DB')
BEGIN
CREATE DATABASE DEMO_DB
END
GO
USE DEMO_DB
GO
------------------------
---some common proc we used
CREATE PROC [dbo].[sp_generate_class] @tableName varchar(200)
AS
BEGIN
declare @Result varchar(max) = 'public class ' + @TableName + '
{'
select @Result = @Result + '
public ' + ColumnType + NullableSign + ' ' + ColumnName + ' { get; set; }
'
from
(
select
replace(col.name, ' ', '_') ColumnName,
column_id ColumnId,
case typ.name
when 'bigint' then 'long'
when 'binary' then 'byte[]'
when 'bit' then 'bool'
when 'char' then 'string'
when 'date' then 'DateTime'
when 'datetime' then 'DateTime'
when 'datetime2' then 'DateTime'
when 'datetimeoffset' then 'DateTimeOffset'
when 'decimal' then 'decimal'
when 'float' then 'double'
when 'image' then 'byte[]'
when 'int' then 'int'
when 'money' then 'decimal'
when 'nchar' then 'string'
when 'ntext' then 'string'
when 'numeric' then 'decimal'
when 'nvarchar' then 'string'
when 'real' then 'double'
when 'smalldatetime' then 'DateTime'
when 'smallint' then 'short'
when 'smallmoney' then 'decimal'
when 'text' then 'string'
when 'time' then 'TimeSpan'
when 'timestamp' then 'DateTime'
when 'tinyint' then 'byte'
when 'uniqueidentifier' then 'Guid'
when 'varbinary' then 'byte[]'
when 'varchar' then 'string'
else 'UNKNOWN_' + typ.name
end ColumnType,
case
when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier')
then '?'
else ''
end NullableSign
from sys.columns col
join sys.types typ on
col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
where object_id = object_id(@TableName)
) t
order by ColumnId
set @Result = @Result + '
}'
PRINT @Result
END
GO
---------
CREATE PROC [dbo].[USP_Lazy_GenerateParamester4Proc] @tableName VARCHAR(200)
AS
BEGIN
SELECT
CASE
WHEN t.Name LIKE '%char' THEN
'@' + c.name + ' ' + t.name + '(' +CAST(c.max_length AS VARCHAR(max))+ '),'
ELSE
'@' + c.name + ' ' + t.name + ','
END AS 'fullDatatype',
c.name as 'Column Name' ,
'@' + c.name + ',' as N'Biến' ,
c.name + '=@' + c.name + ',' as N'Gán' ,
t.Name 'Data type',
c.max_length 'Max Length',
c.precision ,
c.scale ,
c.is_nullable,
ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM
sys.columns c
INNER JOIN
sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN
sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN
sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
c.object_id = OBJECT_ID(@tableName)
END
GO
------------------end-----
CREATE proc [dbo].[USP_MakeResponse](@status varchar(50), @description nvarchar(1000), @jsonData nvarchar(max)='')
as
begin
select @status Status, @description as Description, @jsonData AS Data
END
--You need to check if the table exists
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='tbl_users' and xtype='U')
BEGIN
CREATE TABLE [dbo].[tbl_users](
[id] [INT] IDENTITY(1,1) NOT NULL,
[f_name] [NVARCHAR](50) NOT NULL,
[l_name] [NVARCHAR](50) NOT NULL,
[dob] [DATE] NULL,
[email] [NVARCHAR](200) NULL,
[phone] [VARCHAR](20) NULL,
[created_date] [DATETIME] NULL,
[created_user] [VARCHAR](50) NULL,
[updated_date] [DATETIME] NULL,
[updated_user] [VARCHAR](50) NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[tbl_users] ADD DEFAULT (GETDATE()) FOR [created_date]
INSERT INTO dbo.tbl_users
(
f_name,
l_name,
dob,
email,
phone,
created_user
)
VALUES
( 'TONA','DINH', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
( 'MEO','THAO', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
( 'KHANG','QUOC', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
( 'THAO','NGO', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
( 'MESSI','LEONEL', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
( 'RONALDO','CRITIANO', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
( 'NEYMAR','JR', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' )
END
SELECT * FROM dbo.tbl_users
GO
--------------------end common------------------------
CREATE PROC USP_User_Get @id VARCHAR(MAX)=''--@id=2 || '1,5,6,4,8, ...' || ''
AS
BEGIN
SELECT * FROM tbl_users WHERE exists
(SELECT value FROM STRING_SPLIT(IIF(ISNULL(@id,'')='', CONCAT(id,''), @id), ',')
WHERE ltrim(rtrim(value)) = id)
END
GO
--EXEC USP_User_Get '2,9'
CREATE PROC USP_User_Save
(
@id int,
@f_name varchar(100),
@l_name varchar(100),
@dob date,
@username VARCHAR(50),
@email varchar(200),
@phone varchar(20)
)
AS
BEGIN
DECLARE @isExists INT=0, @des NVARCHAR(1000)
SELECT @isExists=COUNT(*) FROM tbl_users WHERE id=@id;
IF(@isExists>0)
BEGIN
UPDATE dbo.tbl_users
SET
f_name=@f_name,
l_name=@l_name,
dob=@dob,
updated_user=@username,
updated_date=GETDATE(),
email=@email,
phone=@phone
WHERE id=@id;
SET @des=CONCAT(N'Updated Successfully user: ', @f_name )
EXEC dbo.USP_MakeResponse @status = 'OK', -- varchar(50)
@description = @des -- nvarchar(1000)
END
ELSE
BEGIN
INSERT INTO dbo.tbl_users
(
f_name,
l_name,
dob,
created_user,
created_date,
email,
phone
)
VALUES
( @f_name,
@l_name,
@dob,
@username,
GETDATE(),
@email,
@phone
)
SET @des=CONCAT(N'Added Successfully user: ', @f_name )
EXEC dbo.USP_MakeResponse @status = 'OK', -- varchar(50)
@description = @des -- nvarchar(1000)
END
END
GO
CREATE PROC [dbo].[USP_User_Delete] @id INT
AS
BEGIN
SET XACT_ABORT ON
BEGIN TRAN
BEGIN TRY
DELETE FROM dbo.tbl_users WHERE id=@id;
EXEC dbo.USP_MakeResponse @Status = 'OK', -- varchar(50)
@Description = N'Deleted !' -- nvarchar(1000)
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
DECLARE @ErrorMessage NVARCHAR(2000)
SELECT @ErrorMessage = N'Error: ' + ERROR_MESSAGE()
EXEC dbo.USP_MakeResponse @Status = 'ERROR', -- varchar(5)
@Description =@ErrorMessage -- nvarchar(max)
--RAISERROR(@ErrorMessage, 16, 1)
END CATCH
END
GO
EXEC sp_generate_class 'tbl_users'
EXEC [USP_Lazy_GenerateParamester4Proc] 'tbl_users'
GO
SELECT * FROM dbo.tbl_users
GO
3. Thay đổi thông tin SQL Config cho đúng với thông tin trên SQL server của bạn ở file appsettings.json: Lưu ý: xóa các phần được chú thích đi:
{
...,
"AllowedHosts": "*",
"SQLSettings":{
"Host":"localhost", //Server Instance
"DBName":"DEMO_DB", //Database Name
"User":"as" //user Login Server
//Password: *** //password will be saved in secret
}
}
dotnet user-secrets init
dotnet user-secrets set SQLSettings:Password your_password_login_to_server
dotnet run
Mặc định api của mình sẽ online ở địa chỉ:
https://localhost:5001/swagger/index.html
Hoặc bạn có thể sử dụng Postman để test với đường dẫn: https://localhost:5001/users
Cám ơn vì đã theo dõi bài viết !
HAPPY CODING ♡♡♡