效果图:
1.appsettings.json 配置文件,连接数据库
"ConnectionStrings": {
"connString": "server=.; database=CRM; uid=sa; pwd=123456;Encrypt=True;TrustServerCertificate=True;"
}
2. Program.cs
public class Program
{
public static void Main(string[] args)
{
// builder构建器,把当前应用程序构建(编译,生成)。主要提供一个Ioc
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();// 把所有的控件器“扔”到Ioc容器
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//注册上下文:AOP里面可以获取IOC对象,如果有现成框架比如Furion可以不写这一行
builder.Services.AddHttpContextAccessor();
//注册SqlSugar用AddScoped
builder.Services.AddScoped<ISqlSugarClient>(s =>
{
//1. 构建配置对象
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) // 配置文件的目录
// optional: true如果该文件不存在也不会抛出异常
//reloadOnChange: true表示当配置文件发生改变时自动重新加载配置
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
IConfigurationRoot configuration = configBuilder.Build();
//2. 获取连接字符串
string? connString = configuration.GetConnectionString("connString");
//3. 创建SqlSugarClient实例
SqlSugarClient sqlSugar = new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.SqlServer,//指定数据库类型
ConnectionString = connString,
IsAutoCloseConnection = true,//自动关闭数据库连接
},
db =>
{
//配置了一个AOP(面向切面编程)
db.Aop.OnLogExecuting = (sql, pars)=>{ };
});
return sqlSugar;
});
// 把服务“扔”到Ioc
builder.Services.AddSingleton<IStudent, StudentService>();
// app当前应用程序实例
// 向应用程序的Ioc容器中“扔”了很多的服务,必须构建之后,服务才和当前应用融合。
var app = builder.Build();
if (app.Environment.IsDevelopment()) // 判断是否是开发环境,才启用接口调试的功能(即使用Swagger)
{
app.UseSwagger(); // 规律:UseXXX() ,使用某种服务提供的功能。
app.UseSwaggerUI();
}
app.UseHttpsRedirection();// 一个中间件,用于将HTTP请求重定向到HTTPS
app.UseAuthorization();// 授权
// 把控件器中定义的各种接口(服务,方法)映射成一个“地址”
app.MapControllers();
app.Run();
}
}
3.Models中的Student
[SugarTable("Student")]
public class Student
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
[SugarColumn(IsNullable = false, ColumnDataType = "varchar(50)")]
public string Name { get; set; }
}
4.Services中的IStudent和StudentService
public interface IStudent
{
bool Add(Student model);
List<Student> Search(string strWhere);
bool Update(Student model);
bool Delete(int id);
}
public class StudentService : IStudent
{
public bool Add(Student model)
{
return true;
}
public bool Delete(int id)
{
return true;
}
public List<Student> Search(string strWhere)
{
// 模拟数据,省略读取数据库的逻辑:ORM框架可选:ADO.NET, EF, Dapper等。
return new List<Student>()
{
new Student(){ Id=1,Name="张三"},
new Student(){ Id=2,Name="李四"}
};
}
public bool Update(Student model)
{
return true;
}
}
5.Controllers中的StuddentController
规律:
查询可以使用查询字符串传参[FromQuery]和路径传参{id}/{name}。不涉及安全性。
提交,修改,删除这些动作是有危险,建议使用请求体传参[FromBody]
[ApiController]
[Route("api/[controller]")] // 生成路由:api/Student/XXX
public class StuddentController : ControllerBase
{
private readonly IStudent stdentService;
private readonly ISqlSugarClient db;
public StuddentController(IStudent stdentService, ISqlSugarClient db)
{
this.stdentService = stdentService;
this.db = db;
}
#region GET 查询
// HttpGet特性表示是GET请求,主要用来获取数据
[HttpGet("S1")] // api/Student/S1
public IEnumerable<Student> Hello()
{
return new List<Student>()
{
new Student(){ Id=1,Name="zs"},
new Student(){ Id=2,Name="ls"},
};
}
[HttpGet("S2")] // api/Student/S2
public IEnumerable<Student> Hello2()
{
// 使用SqlSugar ORM框架
return this.db.Queryable<Student>().ToList();
}
// GET请求传参问题? 异步GET?
//传参方式1:使用查询字符串 ?key1=val1&key2=val2
[HttpGet("S3")]
public IEnumerable<Student> Hello3(string? name)
{
ISugarQueryable<Student> query = this.db.Queryable<Student>();
if (!string.IsNullOrEmpty(name))
{
query = query.Where(s => s.Name.Contains(name));
}
return query.ToList();
}
// 传参数方式2:占位符(路径参数)
[HttpGet("S4/{name}")] //friendly url友好的URL,利于推广
public IEnumerable<Student> Hello4(string? name)
{
ISugarQueryable<Student> query = this.db.Queryable<Student>();
if (!string.IsNullOrEmpty(name))
{
query = query.Where(s => s.Name.Contains(name));
}
return query.ToList();
}
[HttpGet("S5")]
public IEnumerable<Student> Hello5([FromQuery] string? name)
{
ISugarQueryable<Student> query = this.db.Queryable<Student>();
if (!string.IsNullOrEmpty(name))
{
query = query.Where(s => s.Name.Contains(name));
}
return query.ToList();
}
// 异步Get方式1
[HttpGet("S6")]
public async Task<List<Student>> Hello6()
{
return await db.Queryable<Student>().ToListAsync();
}
//异步Get方式2:返回简单类型
[HttpGet("S7")]
public async IAsyncEnumerable<int> Hello7()
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(1000);// 模拟长时间处理
yield return i; // yield生成
}
}
// 异步Get方式2:返回复杂类型
[HttpGet("S8")]
public async IAsyncEnumerable<Student> Hello8()
{
for (int i = 0; i < 3; i++)
{
await Task.Delay(1000);
yield return new Student() { Id = i, Name = "name" + 1 };// yield生成
}
}
#endregion
#region Post 提交
[HttpPost("add1")]
public IActionResult Add1()
{
// 响应的格式:https://blog.youkuaiyun.com/weixin_43394129/article/details/132444340
// 常用的响应格式:OkResult、JsonResult、 BadRequestResult、NotFoundResult、 NoContentResult
// BadRequestResult 400 客户端请求的语法错误,服务器无法理解
//BadRequest();
// NotFoundResult 404 请求的路径不存在。
//NotFound();
// NoContentResult 没有内容响应
//NoContent();
// OkResult 200成功响应
var obj = new //创建匿名对象
{
Code = 200, //状态码
Message = "添加成功!",
Data = "hello world" //实际要返回的数据
};
return Ok(obj);//在ASP.NET Core Web API中的一种常见返回方式
}
// POST请求传参,推荐使用FromBody,复杂数据类型(引用类型)webapi可以推断,FromBody省略
[HttpPost("add2")]
public IActionResult Add2([FromBody] Student model)
{
this.db.Insertable<Student>(model).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "添加成功!"
});
}
// 异步的Post请求
[HttpPost("add3")]
public async Task<IActionResult> Add3([FromBody] Student model)
{
await this.db.Insertable<Student>(model).ExecuteCommandAsync();
return Ok(new
{
Code = 200,
Message = "添加成功!"
});
}
#endregion
#region PUT 修改
// 传参方式1:FromBody
[HttpPut("put1")]
public IActionResult Put1([FromBody] Student model)
{
this.db.Updateable<Student>(model).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "修改成功!"
});
}
// 传参方式2:路径参数(占位符)
[HttpPut("pu2")]
public IActionResult Put2(int id,string name)
{
Student model = this.db.Queryable<Student>().InSingle(id);
model.Name = name;
this.db.Updateable<Student>(model).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "修改成功!"
});
}
[HttpPut("put3/{id}/{name}")]
public IActionResult Put3([FromRoute] int id, [FromRoute] string name)
{
Student model = this.db.Queryable<Student>().InSingle(id);
model.Name = name;
this.db.Updateable<Student>(model).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "修改成功!"
});
}
// 传参方式3:查询字符串(传递的参数出现在URL中,容易被普通用户修改。不安全)
[HttpPut("put4")]
public IActionResult Put4([FromQuery] int id, [FromQuery] string name)
{
Student model = this.db.Queryable<Student>().InSingle(id);
model.Name = name;
this.db.Updateable<Student>(model).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "修改成功!"
});
}
// 异步的PUT
[HttpPut("put5")]
public async Task<IActionResult> Put5([FromBody] Student model)
{
await this.db.Updateable<Student>(model).ExecuteCommandAsync();
return Ok(new
{
Code = 200,
Message = "修改成功!"
});
}
#endregion
#region Delete 删除
// 传参方式1:请求体
[HttpDelete("del1")]
public IActionResult Del1([FromBody] int id)
{
this.db.Deleteable<Student>(id).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "删除成功!"
});
}
// 传参方式2:路径参数
[HttpDelete("del2/{id}")]
public IActionResult Del2([FromRoute] int id)
{
this.db.Deleteable<Student>(id).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "删除成功!"
});
}
// 传参方式3:查询字符串
[HttpDelete("del3")]
public IActionResult Delete3([FromQuery] int id)
{
this.db.Deleteable<Student>(id).ExecuteCommand();
return Ok(new
{
Code = 200,
Message = "删除成功!"
});
}
//异步的Delete
[HttpDelete("del4")]
public async Task<IActionResult> Del4([FromBody] int id)
{
await this.db.Deleteable<Student>(id).ExecuteCommandAsync();
return Ok(new
{
Code = 200,
Message = "删除成功!"
});
}
#endregion
}