- [SQLSERVER] Loại bỏ Restricted User trên database MSSQL
- [C#] Hướng dẫn tạo mã QRcode Style trên winform
- [C#] Hướng dẫn sử dụng temp mail service api trên winform
- [C#] Hướng dẫn tạo mã thanh toán VietQR Pay không sử dụng API trên winform
- [C#] Hướng Dẫn Tạo Windows Service Đơn Giản Bằng Topshelf
- [C#] Chia sẻ source code đọc dữ liệu từ Google Sheet trên winform
- [C#] Chia sẻ source code tạo mã QR MOMO đa năng Winform
- [C#] Chia sẻ source code phần mềm lên lịch tự động chạy ứng dụng Scheduler Task Winform
- [Phần mềm] Tải và cài đặt phần mềm Sublime Text 4180 full version
- [C#] Hướng dẫn download file từ Minio Server Winform
- [C#] Hướng dẫn đăng nhập zalo login sử dụng API v4 trên winform
- [SOFTWARE] Phần mềm gởi tin nhắn Zalo Marketing Pro giá rẻ mềm nhất thị trường
- [C#] Việt hóa Text Button trên MessageBox Dialog Winform
- [DEVEXPRESS] Chia sẻ code các tạo report in nhiều hóa đơn trên XtraReport C#
- [POWER AUTOMATE] Hướng dẫn gởi tin nhắn zalo từ file Excel - No code
- [C#] Chia sẻ code lock và unlock user trong domain Window
- [DEVEXPRESS] Vẽ Biểu Đồ Stock Chứng Khoán - Công Cụ Thiết Yếu Cho Nhà Đầu Tư trên Winform
- [C#] Hướng dẫn bảo mật ứng dụng 2FA (Multi-factor Authentication) trên Winform
- [C#] Hướng dẫn convert HTML code sang PDF File trên NetCore 7 Winform
- [C#] Hướng dẫn viết ứng dụng chat với Gemini AI Google Winform
[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 ♡♡♡