1、创建WepApi工程 编译工具VS2017
2、选择模板,配置生成参数,如下图
3、创建完工程后,创建一个默认控制器测试。
4、新建两个控制器路由函数(测试用),一个带参数,一个不带参数
5、配置服务跨域访问-有两种方法
方法一:代码配置
5.1 安装跨域所需DLL
5.2 打开WebApiConfig.cs文件,作如下配置,三个*号表示允许所有访问,只做测试,后期再根据需要限制
方法二、在Web.config文件中进行配置,加入如下配置就行了
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="HEAD, GET, POST, PUT, PATCH, DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
启动编译服务程序,获取自动分配端口号
PS:两种配置只能配置其中一种,不能同时配置,调试时还报错,请确认返回数据结构中是否有异常数据
6、编写前端测试文件,用的HBuilder X编写,用ajax访问
6.1 引入js文件
<script src="https://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script>
6.2 编写ajax访问语句
<script>
$.ajax({
url: encodeURI('http://localhost:14464/api/testsend1'),
data: { "": "ids" },
dataType: 'json',
crossDomain: true,
async: true,
success: function (data) {
console.log(data);
},
error: function(data) {
console.log(data);
}
})
</script>
6.3 启动调试网页,返回结果ok1,则代表测试成功--注意,调试时 HBuilder X与visual2017均以管理员权限启动
7、EF数据库使用,用的是三种方式中的code first方式,数据库采用mysql
7.1 新建models层类库
7.2 安装EntityFramework
7.3 安装MYSQL支持包-依赖项:FrameWork >=4.5.2
7.4 新建DbContext上下文文件
7.5 激活Migration的使用
7.5.1 通过 Tools->Nuget Package Manager->Package Manager Console 打开Package Manager Console窗口
7.5.2 Default project选择当前的DbContext所在的项目
7.5.3 通过命令开启Migration:Enable-Migrations
7.5.4 启用后会多出一个Migrations文件夹,文件夹底下有一个Configuration.cs配置文件
7.6 打开这个文件配置数据库自动迁移功能
7.7 打开之前新建的上下文文件,做如下配置,配置自动迁移功能
7.8 新建一个数据model基类BaseEntity
7.9 新建一个User类,继承model基类
7.10 BaseContext数据库上下文里添加public DbSet<User> Users { get; set; }--这句实现生成数据库时就自动创建了user表
7.10 Model类库工程app.config配置文件添下连接字符串和指定MySql连接方式,服务ip和数据库密码根据实际填写
<connectionStrings>
<add name="MySqlConnectionString" connectionString="server=192.168.1.69;port=3306;database=tes_ttt;uid=sa;password=123456" providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.10.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
7.11 在单元测试工程安装7.2和7.3步骤的SQL数据库支持库,同时app.config配置文件也添加7.10的两个配置
7.12 新建测试创建数据库,如下图
7.13 执行测试后就生成了数据库
8、表数据创建与MySql运用
8.1 创建数据访问层DAL类库,引用Models类库
8.2 创建服务基类BaseService
namespace MyWebApiDemo.DAL
{
/// <summary>
/// 服务基类 所有数据服务从这里派生
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
public class BaseService<T> : IDisposable where T : BaseEntity, new()
{
#region 私有成员
protected readonly BaseContext _db;
#endregion 私有成员
#region 构造与释放
public BaseService(BaseContext db)
{
_db = db;
// 数据库日志重定向
}
~BaseService()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true); //I am calling you from Dispose, it's safe
GC.SuppressFinalize(this); //Hey, GC: don't bother calling finalize later
}
protected virtual void Dispose(bool disposing)
{
_db.Dispose();
}
#endregion 构造与释放
#region 增删改
/// <summary>
/// 创建一个新的行
/// </summary>
/// <param name="t">实体对象</param>
/// <param name="saved">是否马上保存到数据库</param>
/// <returns></returns>
public async Task CreateAsync(T t, bool saved = true)
{
_db.Set<T>().Add(t);
if (saved)
await SaveAsync(true);
}
/// <summary>
/// 修改
/// </summary>
/// <param name="t">修改对象</param>
/// <param name="saved">是否保存</param>
/// <returns></returns>
public async Task EditAsync(T t, bool saved = true)
{
_db.Entry(t).State = EntityState.Modified;
if (saved)
await SaveAsync(false);
}
public async Task EditObjectAsync(T t, Action<T> changeAction, bool saved = true)
{
_db.Entry(t).State = EntityState.Unchanged;
changeAction(t);
if (saved)
await SaveAsync(false);
}
public async Task EditObjectAsync(Guid id, Action<T> changeAction, bool saved = true)
{
T t = new T { Id = id };
_db.Entry(t).State = EntityState.Unchanged;
changeAction(t);
if (saved)
await SaveAsync(false);
}
/// <summary>
/// 移除一条数据(IsRemoved=true)
/// </summary>
/// <param name="id">ID</param>
/// <param name="saved">是否马上保存到数据库</param>
/// <returns></returns>
public async Task RemoveAsync(Guid id, bool saved = true)
{
var t = new T()
{
Id = id
};
_db.Entry(t).State = EntityState.Unchanged;
t.IsRemoved = true;
if (saved)
await SaveAsync(false);
}
#endregion 增删改
#region 查询
/// <summary>
/// 获取所有对象
/// </summary>
/// <returns></returns>
public IQueryable<T> GetAll()
{
return _db.Set<T>().AsNoTracking().Where(m => !m.IsRemoved);
}
/// <summary>
/// 按指定条件获取所有对象
/// </summary>
/// <param name="predicate">条件谓词</param>
/// <returns></returns>
//public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate)
//{
// return GetAll().Where(predicate);
//}
/// <summary>
/// 按指定条件和指定顺序获取所有对象,排序依据是创建时间
/// </summary>
/// <param name="predicate">条件谓词</param>
/// <param name="asc">是否升序</param>
/// <returns></returns>
public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate, bool asc = true)
{
var data = GetAll().Where(predicate);
if (asc)
return data.OrderBy(m => m.CreateTime);
else
return data.OrderByDescending(m => m.CreateTime);
}
/// <summary>
/// 按照指定顺序以及指定分页获取全部
/// </summary>
/// <param name="asc">是否升序</param>
/// <param name="pageIndex">分页下标</param>
/// <param name="pageSize">分页大小</param>
/// <returns></returns>
public IQueryable<T> GetAll(bool asc, int pageIndex, int pageSize = 10)
{
if (asc)
return GetAll().OrderBy(m => m.CreateTime)
.Skip(pageSize * pageIndex)
.Take(pageSize);
else
return GetAll().OrderByDescending(m => m.CreateTime)
.Skip(pageSize * pageIndex)
.Take(pageSize);
}
/// <summary>
/// 按照指定条件和指定顺序以及指定分页获取全部
/// </summary>
/// <param name="predicate">条件谓词</param>
/// <param name="asc">是否升序</param>
/// <param name="pageIndex">分页下标</param>
/// <param name="pageSize">分页大小</param>
/// <returns></returns>
public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate, bool asc, int pageIndex, int pageSize = 10)
{
return GetAll(predicate, asc).Skip(pageSize * pageIndex).Take(pageSize);
}
/// <summary>
/// 按照ID获取一条数据(如果未找到,则返回null)
/// </summary>
/// <param name="id">ID</param>
/// <returns></returns>
public async Task<T> GetOne(Guid id)
{
return await GetAll().FirstOrDefaultAsync(m => m.Id == id);
}
#endregion 查询
#region 保存
/// <summary>
/// 马上保存到数据库
/// </summary>
/// <param name="isValidate">是否校验数据(默认是)</param>
/// <returns></returns>
public async Task SaveAsync(bool isValidate = true)
{
if (isValidate)
{
await _db.SaveChangesAsync();
}
else
{
_db.Configuration.ValidateOnSaveEnabled = false;
await _db.SaveChangesAsync();
_db.Configuration.ValidateOnSaveEnabled = true;
}
}
#endregion 保存
}
}
8.3 创建用户服务类
namespace MyWebApiDemo.DAL
{
public class UserService : BaseService<User>
{
public UserService(BaseContext db) : base(db)
{
}
}
}
8.4 创建业务逻辑层BLL,引用DAL与Models
8.5 创建用户管理类-实现添加一个用户
namespace MyWebApiDemo.BLL
{
public class UserManager
{
public static async Task<User> CreateUser(string account, string pwd, string name)
{
try
{
using (var db = new BaseContext())
using (var userSvc = new UserService(db))
{
User user = new User
{
LoginAccount = account,
Password = pwd,
UserName = name
};
await userSvc.CreateAsync(user);
return user;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}
8.5 单元测试添加用户,测试成功后会在数据库user表中看到这个记录,如下图
[TestMethod]
public void TestAddOneUser()
{
try
{
UserManager.CreateUser("test001", "123456", "张三").Wait();
}
catch(Exception ex)
{
}
}
至此,整个过程到此告一段落