背景
目前公司开发的程序为C/S模式(客户端+服务器)的方式开发,但是在实际的应用过程中需要开放一些web服务去给三方使用,比如:和微信公众号对接。
对接需要按WebApi的形式去提供给外部系统,这样就会导致需要基于业务数据重新开发WebApi的服务,并将原有的C/S业务方法开放接口,供WebApi调用。
那么如果我们是从无到有开发新项目的时候,是否需要改善一下设计的模式来达到:不管是C/S还是B/S都能够同时获取到业务数据。
设计思路
项目大致采用以下结构:
【SJ.WebApi】.Net MVC WebAPI-可部署Swagger UI提供给外部系统调用的WebApi接口
【SJ.Model】类库-实体
【SJ.IBLL】类库-接口层
【SJ.BLL】类库-业务层
【SJ.UI】WinForm-客户端UI层
数据请求示例
开发实例
用户表:
SELECT * FROM dbo.[User]
按规范创建接口类:
【SJ.IBLL】接口层--》IUserService.cs
使用面向接口开发的原则,业务调用时统一通过用户接口:IUserService去调用业务方法
namespace SJ.IBLL
{
public interface IUserService
{
/// <summary>
/// 用户登录
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
BaseModel<bool> CheckLogin(User user);
/// <summary>
/// 查询所有用户
/// </summary>
/// <returns></returns>
List<User> QueryAllUser();
/// <summary>
/// 添加用户信息
/// </summary>
/// <returns></returns>
BaseModel<bool> AddUser(User user);
}
}
【SJ.BLL】业务层--》UserService.cs
namespace SJ.BLL.Service
{
public class UserService: IUserService
{
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "Data Source=localhost;Initial Catalog=CS_BS_WEBAPI_TEST;User Id=sa;Password=123!@#;",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true
});
/// <summary>
/// 用户登录
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public BaseModel<bool> CheckLogin(User user)
{
BaseModel<bool> result = new BaseModel<bool>();
result.Rt = true;
result.Rd = "登录成功";
result.Rn = 1;
var users = db.Queryable<User>().Where(o => o.UserName == user.UserName && o.PassWord == user.PassWord).ToList();
if (users.Count == 0)
{
result.Rt = false;
result.Rd = "账号或密码错误";
result.Rn = -1;
}
return result;
}
/// <summary>
/// 查询所有用户
/// </summary>
/// <returns></returns>
public List<User> QueryAllUser()
{
var users = db.Queryable<User>().ToList();
return users;
}
/// <summary>
/// 添加用户信息
/// </summary>
/// <returns></returns>
public BaseModel<bool> AddUser(User user)
{
BaseModel<bool> result = new BaseModel<bool>();
result.Rt = true;
result.Rd = "用户注册成功";
result.Rn = 1;
int tl = db.Insertable(user).ExecuteCommand();
if (tl <= 0)
{
result.Rt = false;
result.Rd = "用户注册失败";
result.Rn = -1;
}
return result;
}
}
}
因为不管是C/S客户端还是B/S控制器做数据请求前必须先new IUserService()实例化接口,此时因为接口的特性不允许被实例化。
我们需要创建一个工厂类,为业务调用时生成对应的业务接口。
【SJ.IBLL】接口层--》IUserFactory.cs
使用反射的原理创建接口的子类:
namespace SJ.IBLL
{
public class IUserFactory
{
public static IUserService CreateUserService()
{
Type type = typeof(IUserService);
IUserService service = (IUserService)Activator.CreateInstance(System.Type.GetType("SJ.BLL.Service.UserService,SJ.BLL"), null);
return service;
}
}
}
客户端调用业务:
/// <summary>
/// 创建接口
/// </summary>
IUserService iserver = IUserFactory.CreateUserService();
//请求数据
var result = iserver.CheckLogin(user);
WebApi接口调用业务:
/// <summary>
/// 创建接口
/// </summary>
IUserService iserver = IUserFactory.CreateUserService();
/// <summary>
/// 用户登录
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[HttpPost]
public BaseModel<bool> CheckLogin(User user)
{
return iserver.CheckLogin(user);
}
遇到的坑
1.net Core 5.0 WebApi发布到IIS报错
访问报错:
HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效。
解决方案:
1.给发布文件夹增加Everyone的所有权限
2.安装对应版本的windows-hosting-bundle-installer
下载地址:https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/runtime-aspnetcore-5.0.17-windows-hosting-bundle-installer
在完成1、2两个步骤之后,访问IIS下的webapi站点,还是报错404
3.修改web.config文件,追加以下内容
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
4.开发过程中添加控制器方法后访问报错
将控制器默认的路由设置[Route("[controller]")],修改为[Route("api/[controller]/[action]")],重新启动项目成功。
项目源码
https://gitee.com/soulsjie/DoNet_BS_CS_WBAPI.git