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了。
