Asp.net WebAPI+Dapper搭建API服务接口

提到WebApi接口,一般会想到以前用到的WebService和WCF服务。这三个技术都是用来创建服务接口,只不过WebAPI用起来更简单,不像WebServive、WCF,尤其是WCF服务配置很复杂。

什么是WebApi

  • 1 这是一个简单的构建HTTP服务的新框架
  • 2 在.net平台上Web API 是一个开源的、理想的、构建RES-ful服务的技术,最新版的Asp.net Core WebApi可以跨平台。
  • 3可以使用HTTP的全部特点(比如URIs、request/response头,缓存,版本控制,多种内容格式)
  • 4它也支持MVC的特征,像路由、控制器、行为、过滤器、模型绑定、控制反转(IOC)或依赖注入(DI),单元测试。这些可以使程序更简单、更健壮
  • 5可以发布部署到IIS上和还可以借用其他技术如(OWIN)部署在控制台(微软新技术.net core的MVC 和webapi自动支持寄宿到控制台项目)
  • 6 一个轻量级的框架,并且对限制带宽的设备,比如智能手机平板等支持的非常好
  • 7WebAPI数据格式可以转换成Json、XML 或者任何你想转换的自定义格式。

一项目搭建

这个项目目的:使用Dapper读取MySQL数据库的用户表,把对用户的增删改的操作接口通过WebAPI发布出去

首先新建一个空白解决方案,命名WebAPIService,并添加一个空白文件,命名Asp.netWebAPI,在这个空白文件夹下创建项目。
image.png
在文件Asp.netWebAPI,右键添加 Web项目,命名APIServer
image.png

选择web模板Web API


image.png
在文件Asp.netWebAPI,添加两个类库,APIDAL与APIModel,创建完如下图:
image.png

是个编程小白都能看得懂这么简单的结构。在此只介绍WebAPI的怎样使用,实际架构比这复杂的多,不再叙说。

APIDAL层和APIModel层设计

在Mysql数据库创建了用户表,
在Mysql数据库创建了用户表,本项目主要介绍了对用户表的增删改查等的接口的实现过程。

APIDAL层通过使用Dapper操作用户表。
下面是用户表的数据结构(用户表主要存储用户的基本信息。如姓名,年龄,密码等)

mysql> describe user;
+------------+--------------+------+-----+----------------------------------+----------------+
| Field      | Type         | Null | Key | Default                          | Extra          |
+------------+--------------+------+-----+----------------------------------+----------------+
| ID         | int(11)      | NO   | PRI | NULL                             | auto_increment |
| Name       | varchar(255) | NO   |     | NULL                             |                |
| Age        | int(11)      | YES  |     | NULL                             |                |
| Salary     | float        | NO   |     | NULL                             |                |
| DaptID     | int(12)      | NO   | MUL | 2                                |                |
| CreateTime | datetime     | NO   |     | CURRENT_TIMESTAMP                |                |
| Pwd        | varchar(255) | NO   |     | 202CB962AC59075B964B07152D234B70 |                |
+------------+--------------+------+-----+----------------------------------+----------------+
7 rows in set (0.07 sec)

在APIModel层添加用户Userinfo类

   /// <summary>
   /// 用户信息类
   /// </summary>
   public class Userinfo
   {

       /// <summary>
       /// 用户编号
       /// </summary>
       public int id { get; set; }
       /// <summary>
       /// 姓名
       /// </summary>
       public string name { get; set; }
       /// <summary>
       /// 密码
       /// </summary>
       public string pwd { get; set; }
       /// <summary>
       /// 年龄
       /// </summary>
       public int age { get; set; }
       /// <summary>
       /// 月薪
       /// </summary>
       public double salary { get; set; }
       /// <summary>
       /// 部门编号
       /// </summary>
       public int deptID { get; set; }
       /// <summary>
       /// 部门名称
       /// </summary>
       public string DapName { get; set; }
       /// <summary>
       /// 创建时间
       /// </summary>
       public DateTime createtime { get; set; }

   }

在APIDAL层添加读取与操作数据库UserInfoDal类UserInfoDal

    /// <summary>
    /// 用户信息数据库操作类
    /// </summary>
    public partial class UserInfoDal
    {
        static readonly string ConnectionString = ConfigurationManager.AppSettings["MySqlDBConnectionString"];
        
        #region 查询相关操作
        /// <summary>
        /// 查询所有用户信息
        /// </summary>
        /// <returns></returns>
        public List<Userinfo> GetAllUserInfo()
        {
            using (MySqlConnection connection = new MySqlConnection(ConnectionString))
            {
                string sql = "select `user`.`Name`,`user`.ID,`user`.Salary,`user`.CreateTime  ,department.DapName from `user` INNER JOIN department on `user`.DaptID = department.DaptID; ";
                var query = connection.Query<Userinfo>(sql);
                return query.ToList();
            }                  
        }
#endregion
        #region 查询单个信息
        /// <summary>
        /// 查询单个用户的信息
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public Userinfo GetUserInfo(int ID)
        {      
            StringBuilder Sqlstr = new StringBuilder();
            Sqlstr.Append(" select `user`.`Name`,`user`.ID,`user`.Salary,`user`.CreateTime from `user` ");
            Sqlstr.Append(" where ID=@ID");
            using (MySqlConnection connection = new MySqlConnection(ConnectionString))
            {             
                var query = connection.Query<Userinfo>(Sqlstr.ToString(),new {ID}).SingleOrDefault();
                return query;
            }
        }
        #endregion 

        #region 分页
        /// <summary>
        /// 用户信息分页查询接口
        /// </summary>
        /// <param name="PageNumber">要查询的第几页</param>
        /// <param name="PageSize">每页要显示几行数据</param>
        /// <param name="TotalItemCount">返回的总条数</param>
        /// <param name="TotalPageCount">返回的总页数</param>
        /// <returns></returns>
        public List<Userinfo> GetUserInfoByPage(int PageNumber, int PageSize, out int TotalItemCount, out int TotalPageCount)
        {
            int pagestart = 0;
            TotalItemCount = 0;
            TotalPageCount = 0;
            pagestart = (PageNumber - 1) * PageSize;
            StringBuilder Sqlstr1 = new StringBuilder();
            Sqlstr1.Append("select Count(user.ID) FROM user;");
            using (MySqlConnection connection = new MySqlConnection(ConnectionString))
            {
                TotalItemCount= connection.ExecuteScalar<int>(Sqlstr1.ToString());
            }               
            TotalPageCount = TotalItemCount / PageSize + 1;

            StringBuilder Sqlstr2 = new StringBuilder();
            Sqlstr2.Append($"select * from user limit { pagestart },{ PageSize};");
            using (MySqlConnection connection = new MySqlConnection(ConnectionString))
            {
             var result=  connection.Query<Userinfo>(Sqlstr2.ToString());
                if (result.Count() > 0 && result != null)
                {
                    return result.ToList();
                }
                return null;
            }
        }
        #endregion
}

三 APISever层接口设计

修改ValuesController控制器代码(同MVC控制器,就是一个类。这个类是添加APISever 这个WebAPI项目时vs模板自动生成的一个类),ValuesController类相当于API接口的实现类。,ValuesController在这通过调用APIDAL层封装的读取数据库用户表的方法 UserInfoDal,向外发布接口,此类必须继承ApiController。(这是WebAPI框架规定的继承,不能改变)

    /// <summary>
    /// 用户信息类接口
    /// </summary>
    public class ValuesController : ApiController
    {
        UserInfoDal dal = new UserInfoDal();
        /// <summary>
        /// 查询所有人员信息
        /// </summary>
        /// <returns></returns>

        public IEnumerable<Userinfo> GetUserData()
        {
            List<Userinfo> sermodel = new List<Userinfo>();
            sermodel = dal.GetAllUserInfo();
            return sermodel;
        }
        /// <summary>
        /// 根据用户ID查询用户信息
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        //[AcceptVerbs("GET", "HEAD")]
        public IHttpActionResult UpdateList(int id)
        {
            Userinfo x = dal.GetUserInfo(id);
            if (x != null)
            {
                return Ok(x);
            }
            return NotFound();          
        }
        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="model">用户信息实体</param>
        /// <returns></returns>
        public IHttpActionResult UpdateUserInfo(Userinfo model)
        {
            if (dal.UpdateUserInfo(model))
            {
                return Json(new { success = "成功" });
            }
            return Json(new { success = "失败" });
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        public IHttpActionResult Delete(int id)
        {
            if (dal.DeleteUserInfo(id))
            {
                return Ok(1);
            }
            else
            {
                return Ok(0);
            }
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="model">分页实体类</param>
        /// <returns></returns>    
        [HttpPost]      
        public IHttpActionResult Paging([FromBody]PageModel model)
        {
            //int TotalItemCount = 0;//总条数
            //int TotalPageCount = 0;//总页数
            List<Userinfo> list = new List<Userinfo>();
            list = dal.GetUserInfoByPage(PageNumber: model.PageNumber, PageSize: model.PageSize, TotalItemCount: out int TotalItemCount, TotalPageCount: out int TotalPageCount);
            return Ok(new { model = list,  TotalItemCount, TotalPageCount });
        }
        #region 添加
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="model">用户类对象</param>
        /// <returns></returns>
        [HttpGet]//Get请求 g,默认是将参数全部放到了url里面直接以string的形式传递的,参数前需加上[FromUri]否则接收不到数据
        public IHttpActionResult AddPage([FromUri]Userinfo model)
        {
            bool b = dal.AddUser(model);
            if (b)
            {
                return Ok(new { success = "成功" });
            }
            return Ok(new { success = "失败" });
        }
        #endregion
    }

到此一个关于用户信息操作的WebAPI接口创建完成了,简单吧,没什么难度。只要把数据访问层设计好,WebAPI接口层只要创建一个继承ApiController控制器的类,在这个类中
调用DAL层的数据访问接口,这样WebAPI接口就创建好了。

四 WebAPI发布前接口调试

按Ctrl+F5调试

image.png

调试出现的 http://localhost:47362/中的端口号系统随机指定的,在你的电脑中运行可能会出现不同 的端口号。
点击页面上的API
image.png

你会发现刚才在ValuesController控制器中创建的用户信息表的增删改查的接口方法,都详细列举出来了,连注释都有。这里面详细介绍了各个接口的调用方式,传参方式及返回结果形式。一目了然。这正是WebAPI的强大之处,不但简单轻量,连帮助文档都这么友好,比以前的WCF接口明白多了,我以往用WCF接口,如果没有开发WCF的接口的详细文档或者开发WCF接口的人员和你沟通,是不太容易看得懂WCF接口的调用方式的。
在浏览器中调用查询所有人员信息的接口 http://localhost:47362/api/Values/GetUserData

image.png

如果数据的数据出现在页面上,这样Web接口就成功调用出来了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容

  • 本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- B...
    圣杰阅读 3,867评论 0 56
  • 流浪(念出) 像海追赶风儿像天迷情大地我像个孤独患者在这世间流离 见过最美夕阳巧遇人生佳丽在不应该骄傲的年纪选择在...
    奇奇怪怪小技巧阅读 287评论 9 10
  • 一、本周好习惯打卡执行情况: [x]早起打卡(7/7) [x]发“早安”朋友圈(7/7) [x]晨间日记+三只青蛙...
    邱明阅读 126评论 0 0
  • 我将铭记今夜清辉的温柔 莫问我是何缘由 仅是以你为名 书写那从未被吟唱的哀愁 瓮裏里空藏着胜天的权谋 故梦的西风已...
    封章阅读 109评论 0 0