NetCore WebAPI入门

IDE: vs2019

Core版本:.NET Core3.1

调整启动方式

在进行开发webapi项目时,我们为了方便监听程序日志,我们可以选择一控制台方式启动。

image-20210114170339647

配置启动主页

launchSetting.json里我们对启动项进行详细设置。

1
2
3
4
5
6
7
8
9
"WebCore": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "index.html", //启动时的Url
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5000"
}

启用静态资源

在项目根目录创建一个名为wwwroot的文件夹用于存放静态资源。

Startup.cs中, public void Configure(IApplicationBuilder app, IWebHostEnvironment env)方法中添加:

1
app.UseStaticFiles();

启用跨域

ConfigureServices设置跨域

1
2
3
4
5
6
//跨域
services.AddCors(
m => m.AddPolicy(Any, a => a.SetIsOriginAllowed(_ => true).
AllowAnyMethod().
AllowAnyHeader().
AllowCredentials()));

Configure设置启用跨域

1
app.UseCors(Any);

在Controller中启动跨域

1
[EnableCors("Any")]

启用Session和Cookie

基础配置

ConfigureServices

1
2
3
4
5
6
7
//启用Session
services.AddSession(options =>
{
options.Cookie.Name = ".WebCore.Session";
options.IdleTimeout = System.TimeSpan.FromSeconds(120);//设置session的过期时间
options.Cookie.HttpOnly = true;//设置在浏览器不能通过js获得该cookie的值
});

Configure

1
app.UseSession();//UseSession配置在UseMvc之前

Session 帮助类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace WebCore.Tool
{
/// <summary>
/// Session 帮助类
/// </summary>
public class SessionHelper
{
private IHttpContextAccessor _accessor;
private ISession _session;
private IRequestCookieCollection _requestCookie;
private IResponseCookies _responseCookie;

public SessionHelper(HttpContext context)
{
_session = context.Session;
_requestCookie = context.Request.Cookies;
_responseCookie = context.Response.Cookies;
}
/// <summary>
/// 设置session值
/// </summary>
/// <param name="session"></param>
/// <param name="key"></param>
/// <param name="value"></param>
public void SetSession(string key, string value)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(value);
_session.Set(key, bytes);
}
/// <summary>
/// 获取Session值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetSession(string key)
{
byte[] bytes;
_session.TryGetValue(key, out bytes);
if (bytes == null)
{
return "";
}
var value = System.Text.Encoding.UTF8.GetString(bytes);

if (string.IsNullOrEmpty(value))
{
value = string.Empty;
}
return value;
}
}
}

❤️ 要使用Session和Cookie,可以使用IHttpContextAccessor来设置。

1
2
3
4
5
//存储Cookie
accessor.HttpContext.Response.Cookies.Append("userId", res2.Id.ToString());
//取得Cookie
var userId = string.Empty;
accessor.HttpContext.Request.Cookies.TryGetValue("userId", out userId);

依赖注入

startup.csConfigureServices.cs的方法中注入:

1
2
//使用泛型注入一类对象
services.AddTransient<WebCore.Services.OrderService>();

在需要使用的地方的构造函数中注入:

1
2
3
4
5
private readonly OrderService orderService;
public OrderController(OrderService order)
{
this.orderService = order;
}

EF连接数据库

连接Mysql

▶️首先需要安装对应的依赖,包括:

😃记得和netcore 的版本号对应,此文netcore版本号为 3.1

  • EntityFrameworkCore 3.1.8
  • EntityFrameworkCore.Tools 3.0.1
  • Pomelo.EntityFrameworkCore.MySql 3.2.0

image-20210115094744022

配置Mysql 连接字符串
appsetting.json
1
2
3
"ConnectionStrings": {
"MysqlConnection": "Data Source=localhost;Database=coreDb;User ID=root;Password=;pooling=true;port=3306;sslmode=none;CharSet=utf8;"
},
注册连接
Startup.cs
1
2
3
//连接数据库
var connection = Configuration.GetConnectionString("MysqlConnection");
services.AddDbContext<CoreDbContext>(t => t.UseMySql(connection));
EF连接类

在EF中我们需要创建一个数据库上下文对象的类,这个类需要继承自DbContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using Microsoft.EntityFrameworkCore;

namespace WebCore.Models
{
/// <summary>
/// 核心数据库上下文对象
/// </summary>
public class CoreDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Flower> Flowers { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Cart> Carts { get; set; }
public DbSet<Address> Addresses { get; set; }
public DbSet<LeaveWord> LeaveWords { get; set; }
public DbSet<FlowerOrder> FlowerOrders { get; set; }
public DbSet<FlowerPicture> FlowerPictures { get; set; }

public CoreDbContext(DbContextOptions<CoreDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
}
}

EF迁移指令

☑️我们可以使用一下指令来操作EF迁移。

每次使用EF迁移后都会生成一个迁移类,并在数据库中存储迁移的相关信息,可以很方便的使用数据回滚。

指令 作用
Add-Migration xxx 添加一次迁移 迁移名称为xxx
Update-Database 将当前迁移更新于数据库

搭建Model

▶️ 我们可以构建一个基础实体类方便管理共有属性。

BaseEntity.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace WebCore.Models
{
public class BaseEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

public DateTime CreateTime { get; set; } = DateTime.Now;

public DateTime UpdateTime { get; set; } = DateTime.Now;
}
}

特性注解

特性名称 特性作用
[Key] 用于标注实体模型中的主键
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 用于标注Id自增

🙂待更新…

一对一

一对多

多对多

搭建DAL

▶️我们可以搭建一个通用的DAL层来进行数据访问。

BaseService.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using WebCore.Models;

namespace WebCore.DAL
{
public class BaseService<T> : IDisposable where T : BaseEntity
{
private readonly CoreDbContext coreDb;

public BaseService(CoreDbContext coreDb)
{
this.coreDb = coreDb;
}

public void Dispose()
{
coreDb.Dispose();
}

/// <summary>
/// 创建
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
protected async Task<bool> CreateAsync(T t)
{
await coreDb.AddAsync<T>(t);

return coreDb.SaveChangesAsync().Result>0;
}

/// <summary>
/// 编辑
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
protected async Task<bool> EditAsync(T t)
{

coreDb.Set<T>().Update(t);
return await coreDb.SaveChangesAsync()>0;

}

/// <summary>
/// 删除
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
protected async Task Remove(T t)
{
coreDb.Remove<T>(t);
await coreDb.SaveChangesAsync();
}

/// <summary>
/// 获得所有
/// </summary>
/// <returns></returns>
protected IQueryable<T> GetAll(bool asc=true)
{
if (asc)
{
return coreDb.Set<T>().AsNoTracking().OrderBy(m=>m.CreateTime);

}
return coreDb.Set<T>().AsNoTracking();
}

/// <summary>
/// 获得所有
/// </summary>
/// <param name="expression">指定条件</param>
/// <returns></returns>
protected IQueryable<T> GetAll(Expression<Func<T,bool>> expression,bool asc=true)
{
return GetAll(asc).Where(expression);
}


/// <summary>
/// 获得所有并分页
/// </summary>
/// <param name="expression">条件</param>
/// <param name="pageSize">数量</param>
/// <param name="pageIndex">页码</param>
/// <param name="asc">排序</param>
/// <returns></returns>
protected IQueryable<T> GetAllPage(Expression<Func<T, bool>> expression,int pageIndex , int pageSize=10, bool asc = true)
{
return GetAll(asc).Where(expression).Skip(pageSize*pageIndex).Take(pageSize);
}

/// <summary>
/// 获得一个通过id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
protected T GetOne(int id)
{
return GetAll().FirstOrDefault(x => x.Id == id);
}

/// <summary>
/// 获得一个通过条件
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
protected T GetOne(Expression<Func<T, bool>> expression)
{
return GetAll().FirstOrDefault(expression);
}
}
}

搭建Services

搭建Dto