用最清爽的方式開發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 編輯過 |
關鍵字查詢
相關文章
正在查詢... |