asp.net 添加web api接口
工程源码下载:GPS定位系统VUE版本源码下载
在前面章节中,我们添加了“HomeController.cs”和“LoginController.cs”控制器文件,但是功能还没实现。
在添加两个控制器的代码之前,我们需要先添加4个cs文件,如下:

EditDto.cs代码如下:
namespace WebApplicationApi.Dto
{
    public class EditDto
    {
        public string id { get; set; }
        /// <summary>
        /// 经度
        /// </summary>
        public decimal longitude { get; set; }
        /// <summary>
        /// 纬度
        /// </summary>
        public decimal latitude { get; set; }
    }
}
PageDto.cs代码如下:
namespace WebApplicationApi.Dto
{
    public class PageDto
    {
        /// <summary>
        /// 第几页
        /// </summary>
        public int page { get; set; }
        /// <summary>
        /// 每页多少条数据
        /// </summary>
        public int limit { get; set; }
    }
}
Util.cs 代码如下:
using DbEntity.Tables;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
namespace WebApplicationApi.Function
{
    public static class Util
    {
        /// <summary>
        /// 对象转Json
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJson(this object obj)
        {
            lock (obj)
            {
                try
                {
                    return JsonConvert.SerializeObject(obj);
                }
                catch { }
                return null;
            }
        }
        /// <summary>
        /// 转换为MD5加密后的字符串(默认加密为32位)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ToMD5String(this string str)
        {
            MD5 md5 = MD5.Create();
            byte[] inputBytes = Encoding.UTF8.GetBytes(str);
            byte[] hashBytes = md5.ComputeHash(inputBytes);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("x2"));
            }
            md5.Dispose();
            return sb.ToString();
        }
        /// <summary>
        /// 获取token
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public static string getToKen(IConfiguration configuration, User user)
        {
            //1.验证用户账号密码是否正确,暂时忽略,因为我们是模拟登录
            //Payload,存放用户信息
            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.id),
                new Claim(ClaimTypes.Sid, user.id),
                new Claim(ClaimTypes.Name , user.Account),
            };
            //取出私钥并以utf8编码字节输出
            var secretByte = Encoding.UTF8.GetBytes(configuration["JWT:SecretKey"]);
            //使用非对称算法对私钥进行加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            //使用HmacSha256来验证加密后的私钥生成数字签名, 选择签名算法
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            //生成Token
            var expires = Convert.ToDouble(configuration["JWT:Expires"]);
            var Token = new JwtSecurityToken(
                    issuer: configuration["JWT:Issuer"],        //发布者
                    audience: configuration["JWT:audience"],    //接收者
                    claims: claims,                             //存放的用户信息
                    notBefore: DateTime.UtcNow,                 //发布时间
                    expires: DateTime.UtcNow.AddHours(expires), //有效期设置
                    signingCredentials                          //数字签名
                );
            //生成字符串token
            return new JwtSecurityTokenHandler().WriteToken(Token);
        }
    }
}
AjaxResult.cs代码如下:
namespace WebApplicationApi
{
    public class AjaxResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }
        /// <summary>
        /// 错误代码
        /// </summary>
        public string ErrorCode { get; set; }
        /// <summary>
        /// 返回消息
        /// </summary>
        public string Msg { get; set; }
        /// <summary>
        /// 返回数据
        /// </summary>
        public object Data { get; set; }
    }
}
添加完上面两个cs文件之后,我们就可以给控制器添加API了。
LoginController.cs注意实现两个功能:注册和登录。
代码如下:
using DbEntity;
using DbEntity.Tables;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using WebApplicationApi.Function;
namespace WebApplicationApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class LoginController : ControllerBase
    {
        private readonly IConfiguration configuration;
        private readonly ILogger<LoginController> _logger;
        public LoginController(ILogger<LoginController> logger, IConfiguration configuration)
        {
            this.configuration = configuration;
            this._logger = logger;
        }
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userText"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult SignIn(string userName, string userText, string password)
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                if (userName.IsNullOrEmpty()) throw new Exception("用户名不能为空");
                if (userText.IsNullOrEmpty()) throw new Exception("昵称不能为空");
                if (password.IsNullOrEmpty()) throw new Exception("密码不能为空");
                using (MyDbContext db = new MyDbContext())
                {
                    User? u1 = db.Tb_User.FirstOrDefault(x => x.Account.Trim().ToLower() == userName.ToLower());
                    if (u1 != null) throw new Exception("用户名已存在");
                    User? u2 = db.Tb_User.FirstOrDefault(x => x.NickName.Trim().ToLower() == userText.ToLower());
                    if (u2 != null) throw new Exception("昵称已存在");
                    User NewUser = new User()
                    {
                        Account = userName,
                        Password = password.ToMD5String(),
                        NickName = userText,
                        Level = 0,
                    };
                    db.Tb_User.Add(NewUser);
                    db.SaveChanges();
                    res.Success = true;
                }
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPasswd"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Login(string userName, string userPasswd)
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                if (userName.IsNullOrEmpty()) throw new Exception("用户名不能为空");
                if (userPasswd.IsNullOrEmpty()) throw new Exception("密码不能为空");
                userPasswd = userPasswd.ToMD5String();
                using (MyDbContext db = new MyDbContext())
                {
                    var user = db.Tb_User.FirstOrDefault(x => x.Account == userName);
                    if (user == null)
                        throw new Exception($"该用户不存在");
                    if (user.Password != userPasswd)
                        throw new Exception($"密码输入错误");
                    var TokenStr = Util.getToKen(configuration, user);
                    res.Data = new
                    {
                        name = user.NickName,
                        token = $"Bearer {TokenStr}",
                        id = user.id
                    };
                    res.Success = true;
                    db.SaveChanges();
                    db.Dispose();
                }
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
    }
}
HomeController.cs注意实现的功能:地图页面和报表页面所需的所有API。
代码如下:
using DbEntity;
using DbEntity.Tables;
using Link;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.Collections;
using System.Data;
using System.Security.Claims;
using WebApplicationApi.Dto;
using WebApplicationApi.Function;
namespace WebApplicationApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]
    public class HomeController : ControllerBase
    {
        private readonly IConfiguration configuration;
        private readonly ILogger<HomeController> _logger;
        public HomeController(ILogger<HomeController> logger, IConfiguration configuration)
        {
            this.configuration = configuration;
            this._logger = logger;
        }
        #region 报表页面的接口
        /// <summary>
        /// 系统配置
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult mapList(PageDto msg)
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                var claimsPrincipal = this.HttpContext.User;
                var UserId = claimsPrincipal.Claims.FirstOrDefault(r => r.Type == ClaimTypes.Sid)?.Value;
                if (UserId.IsNullOrEmpty())
                    throw new Exception("用户未登录");
                using (MyDbContext db = new MyDbContext())
                {
                    var list = db.Tb_GpsData.OrderBy(x => x.UserId == UserId).ToList();
                    Hashtable hash = new Hashtable();
                    hash["count"] = list.Count();
                    // 翻页
                    list = list.Skip(msg.page * msg.limit).Take(msg.limit).ToList();
                    hash["words"] = list;
                    res.Data = hash;
                    res.Success = true;
                }
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Edit(EditDto msg)
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                using (MyDbContext db = new MyDbContext())
                {
                    var a = db.Tb_GpsData.FirstOrDefault(x => x.id == msg.id);
                    if (a == null) throw new Exception($"未查询到ID:{msg.id}");
                    a.longitude = msg.longitude;
                    a.latitude = msg.latitude;
                    db.SaveChanges();
                    res.Success = true;
                }
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public ActionResult Delete(string id)
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                using (MyDbContext db = new MyDbContext())
                {
                    db.Remove(db.Tb_GpsData.FirstOrDefault(x => x.id == id));
                    db.SaveChanges();
                    res.Success = true;
                }
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
        #endregion
        #region 地图页面的接口
        /// <summary>
        /// 手动下发采集命令
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult SendOrder()
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                // 由于初始化的时候,设置的设备类型是1,设备号也是1,所以这边查询的时候也要按这个参数查询
                var sense = Link.Res.Socs.FirstOrDefault(v => v.equi == 1 && v.equino.ByteToInt() == 1) as Link.Equipment.GpsModel;
                if (sense != null)
                {
                    if (sense.socketstate == 1)
                    {
                        // 下发命令,可以带参数,这里用0
                        int ret = sense.SetState(0);
                        if (ret == 0) res.Msg = "命令发送成功.";
                        if (ret == 1) res.Msg = "命令发送失败.";
                        if (ret == -1) res.Msg = "网络错误.";
                        res.Success = true;
                    }
                    else throw new Exception($"设备链接已断开");
                }
                else throw new Exception($"未查询到设备");
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
        /// <summary>
        /// 获取最新的坐标
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult GetMapPoint(int devid)
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                var claimsPrincipal = this.HttpContext.User;
                var UserId = claimsPrincipal.Claims.FirstOrDefault(r => r.Type == ClaimTypes.Sid)?.Value;
                if (UserId.IsNullOrEmpty())
                    throw new Exception("用户未登录");
                Hashtable pack = new Hashtable();
                int socketstate = 0;
                string update = "";
                GpsData? gps = null;
                var sense = Link.Res.Socs.FirstOrDefault(v => v.equi == 0x01 && v.equino.ByteToInt() == devid && v.user == UserId);
                if (sense != null)
                {
                    socketstate = sense.socketstate;
                    var p = Res.lastmap.FirstOrDefault(x => x.UserId == UserId && x.devid == devid);
                    if (p != null)
                    {
                        update = p.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss");
                        gps = p;
                    }
                }
                pack["socketstate"] = socketstate;
                pack["update"] = update;
                pack["gps"] = gps;
                res.Data = pack;
                res.Success = true;
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
        /// <summary>
        /// 获取设备链接状态
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult GetSocket()
        {
            AjaxResult res = new AjaxResult() { Success = false };
            try
            {
                // 由于初始化的时候,设置的设备类型是1,设备号也是1,所以这边查询的时候也要按这个参数查询
                var sense = Link.Res.Socs.FirstOrDefault(v => v.equi == 1 && v.equino.ByteToInt() == 1) as Link.Equipment.GpsModel;
                if (sense != null)
                {
                    res.Data = (sense.socketstate == 1) ? 1 : 0;
                    res.Success = true;
                }
                else throw new Exception($"未查询到设备");
            }
            catch (Exception e)
            {
                res.ErrorCode = e.Message;
            }
            return Content(res.ToJson());
        }
        #endregion
    }
}
添加完所有代码之后,我们再次运行工程,此时,就可以在Swagger中看到我们的API了。
