《.NET开发之BS+CS混合模式下的应用开发思路》
背景
目前公司开发的程序为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