用最清爽的方式开发dotNet
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
已开源,没啥技术含量,只是一个思路, -> 开源地址前提假设我要做一个简单的api 方式想到清爽,那肯定是简单方便,脑袋第一个念头就是.Net6 推出的miniapi了 官方路子两篇官方文档足以,按照文档step by step 就ok了,其他的需要就加 我的野路子官方是官方,官方走的路子当然还是基于它最标准的搞法,我的路子则是基于国内实际情况 模拟前提场景搞一个普通企业官网的api,那么要求就是以下几点
根据这些要求,我需要引入最基本的就几个:
如果有其他需求,再自己加,一点也不冗余 注意:需要先右键控制台项目,将 代码
var builder = WebApplication.CreateBuilder(args); #region 基本设置 builder.Services.AddMemoryCache(); builder.Services.AddControllers(); builder.Services.Configure<FormOptions>(options => { // 设置上传大小限制256MB options.MultipartBodyLengthLimit = 268435456; }); builder.Services.AddSingleton<SqlSugarMemoryCacheService>(); #endregion #region 授权鉴权 // 添加身份验证和授权中间件 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "ningissuer", ValidAudience = "wr", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("sdfsdfsrty45634kkhxxhtdgdfss345t678xx")) }; }); builder.Services.AddAuthorization(options => { options.AddPolicy("AdminOnly", policy => { policy.RequireClaim("role", "admin"); }); }); #endregion #region swagger builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "企业官网Api", Version = "v1" }); // 添加身份验证 c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey }); // 添加授权要求 c.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] {} } }); // 设置 XML 注释文件的路径 var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); }); #endregion var app = builder.Build(); app.UseSwagger(); app.UseStaticFiles(); // 启用身份验证和授权中间件 app.UseAuthentication(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); // 这里配置了使用控制器的路由 }); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "企业官网Api"); c.RoutePrefix = string.Empty; // 将 Swagger UI 设置为应用程序的根路径 }); ServiceLocator.Instance = app.Services; ServiceLocator.ApplicationBuilder = app; var db = SqlSugarHelper.Db; //数据库初始化 app.MapGet("/seed", async () => { db.CodeFirst.InitTables<SysUserEntity>(); string name = "op"; string pwd = "op"; var loginResult = await db.Queryable<SysUserEntity>().Where(a => !a.IsBan && a.UsePwd == pwd && a.UserName == name).AnyAsync(); if (!loginResult) { await db.Insertable<SysUserEntity>(new SysUserEntity { IsBan = false, UsePwd = pwd, UserName = name }).ExecuteCommandAsync(); } db.CodeFirst.InitTables<FileSourceEntity>(); db.CodeFirst.InitTables<ArticleEntity>(); }); app.MapGet("/health", () => "1024"); app.Run(); 接口就“勉为其难”的新建个api文件夹然后 /// <summary> /// 系统用户 /// </summary> [Route("api/[controller]/[action]")] [ApiController] public class SysUserController : BaseApi { public SysUserController() { } /// <summary> /// 检测Token信息 /// </summary> /// <returns></returns> [HttpGet] [Authorize] public ApiResult CheckToken() { var httpContext = HttpContext; // 从请求头中获取 Authorization 标头的值 var authorizationHeader = httpContext.Request.Headers["Authorization"].FirstOrDefault(); if (!string.IsNullOrEmpty(authorizationHeader) && authorizationHeader.StartsWith("Bearer ")) { // 提取令牌字符串(去除 "Bearer " 前缀) var token = authorizationHeader.Substring(7); var tokenHandler = new JwtSecurityTokenHandler(); var jwtToken = tokenHandler.ReadJwtToken(token); // 获取 ClaimTypes.Name 的值 var username = jwtToken.Claims.FirstOrDefault(claim => claim.Type == "name")?.Value; // 在这里使用 username 进行其他操作 return Success($"当前Token用户是:{username}"); } return Error("Toekn信息解析失败"); } /// <summary> /// 登录 /// </summary> /// <param name="model"></param> /// <returns></returns> [AllowAnonymous] [HttpPost] public async Task<ApiResult> Login(SysUserEntity model) { string secretKey = "sdfsdfsrty45634kkhxxhtdgdfss345t678xx"; var loginResult = await db.Queryable<SysUserEntity>().Where(a => !a.IsBan && a.UsePwd == model.UsePwd && a.UserName == model.UserName).AnyAsync(); // 验证用户名和密码 if (!loginResult) { return Error("账号密码错误"); } // 生成 JWT 令牌 var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(secretKey); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new List<Claim> { new Claim(ClaimTypes.Name, model.UserName), new Claim(JwtRegisteredClaimNames.Jti, model.Id.ToString()), new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.ToString()), new Claim(ClaimTypes.Expiration, DateTime.Now.AddHours(10).ToString()) }), Expires = DateTime.UtcNow.AddDays(7), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature), Issuer = "ningissuer", Audience = "wr",
}; var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); // 返回 JWT 令牌 return Success(new { token = "Bearer " + tokenString }); } } 到这里,基本上已经结束了,剩下的无非加加业务,或者加一些更丰富的组件,什么autofac啦,nacos啦,yarp啦,seq啦 总结对项目而言其实这种方式已经足够适用绝大多数中小公司的普通项目需求了,如果你还要加些限流或者什么中间件的话,也是可以很直观的去加,而不是像某些框架封装一坨又一坨,你在哪加个什么东西要翻找半天,毁坏了原本dotNet自身的生态(指官方文档) 这样出来对的项目也很直观,物尽其才,只要后续开发定好一个规范管理,就不会像你公司那破框架一堆密密麻麻的东西都没使用过的情况出现 对新手而言同时呢,这样构建一个项目框架,也方便新手学习,因为十分的直观,不会对莫名其妙出现的东西感觉到匪夷所思,根本不知道拿来做什么的,像这样需要什么加什么,就对所有加的东西包括nuget包,中间件,或者封装啥的都有个很清晰的认知 对转行到.Net的人而言dotnet官方本身已经是一个大封装了,不要把别的语言思维带到这里,做什么破功能都要自己写,写又写不好,写好了又没文档,人走了之后又坑公司又坑其他.net开发者 结语,给所有中小公司和个人的开发建议马上2024了,.Net的生态已经算是十分丰富了,请不要再试图自行造轮子 举个例子假如你要 别在那自己瞎琢磨封装,对个人而言你瞎封装有什么用对你也没什么好处费时费力,还封装不好,你能保证自己封装完了还会提供详细的文档? 一句很重要的话,我在一线开发从curd干到框架,我觉得很多人都没意识到的一点就是: 就刚才这封装的例子,如果你是自己封装,随便有点变动你是不是要抛下业务需求不管去维护? 代码文件补充SqlSugarHelperpublic class SqlSugarHelper { public static readonly SqlSugarScope Db = new SqlSugarScope(new ConnectionConfig() { ConnectionString = "server=xxx;Database=xxx;Uid=root;Pwd=xxx;Port=6607;Allow User Variables=True;",//连接符字串 DbType = DbType.MySql, IsAutoCloseConnection = true, }, db => { ExternalServicesSetting(db); db.Aop.OnLogExecuting = (sql, pars) => { Console.WriteLine(sql); }; }); /// <summary> /// 拓展配置 /// </summary> /// <param name="db"></param> /// <param name="config"></param> private static void ExternalServicesSetting(SqlSugarClient db) { var cache = ServiceLocator.Instance.GetService<SqlSugarMemoryCacheService>(); db.CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices { DataInfoCacheService = cache, }; } } 该文章在 2023/12/25 16:05:11 编辑过 |
关键字查询
相关文章
正在查询... |