LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

用最清爽的方式開發(fā)dotNet

freeflydom
2023年12月25日 16:5 本文熱度 1077

不管是官方自帶模板還是其他開源搞的,總是一來一大堆,如果你也嫌棄這些過于臃腫,不如看看我這個(gè)方式


已開源,沒啥技術(shù)含量,只是一個(gè)思路, -> 開源地址

前提

假設(shè)我要做一個(gè)簡單的api

方式

想到清爽,那肯定是簡單方便,腦袋第一個(gè)念頭就是.Net6 推出的miniapi了

官方路子

兩篇官方文檔足以,按照文檔step by step 就ok了,其他的需要就加

我的野路子

官方是官方,官方走的路子當(dāng)然還是基于它最標(biāo)準(zhǔn)的搞法,我的路子則是基于國內(nèi)實(shí)際情況
總體思路就是用控制臺改api

模擬前提場景

搞一個(gè)普通企業(yè)官網(wǎng)的api,那么要求就是以下幾點(diǎn)

  • 需要數(shù)據(jù)庫操作

  • 需要授權(quán)鑒權(quán)

  • 需要swagger文檔

  • 需要上傳文件

根據(jù)這些要求,我需要引入最基本的就幾個(gè):

  • Swashbuckle.AspNetCore (swagger相關(guān))

  • SqlSugarCore (sqlsugar Orm) (用啥都可以,例如還有freesql)

  • Microsoft.AspNetCore.Authentication.JwtBearer (授權(quán)鑒權(quán)這里用簡單的jwt)

  • Mapster (dto和entity互轉(zhuǎn))

如果有其他需求,再自己加,一點(diǎn)也不冗余

注意:需要先右鍵控制臺項(xiàng)目,將 <Project Sdk="Microsoft.NET.Sdk"> 改為 <Project Sdk="Microsoft.NET.Sdk.Web"> 其原因可以去官網(wǎng)翻找資料感悟一下

代碼

dotNet 幾忘了,反正很早就是通用主機(jī)了,如果你同時(shí)還要搞blazor server啥的,把這一坨封裝一下即可,通用的

Program.cs 里面直接無腦寫下以下代碼

var builder = WebApplication.CreateBuilder(args);


#region 基本設(shè)置

builder.Services.AddMemoryCache();

builder.Services.AddControllers();

builder.Services.Configure<FormOptions>(options =>

{

    // 設(shè)置上傳大小限制256MB

    options.MultipartBodyLengthLimit = 268435456;


});

builder.Services.AddSingleton<SqlSugarMemoryCacheService>();

#endregion


#region 授權(quán)鑒權(quán)



// 添加身份驗(yàn)證和授權(quán)中間件

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 = "企業(yè)官網(wǎng)Api", Version = "v1" });


    // 添加身份驗(yàn)證

    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme

    {

        Description = "JWT Authorization header using the Bearer scheme",

        Name = "Authorization",

        In = ParameterLocation.Header,

        Type = SecuritySchemeType.ApiKey

    });


    // 添加授權(quán)要求

    c.AddSecurityRequirement(new OpenApiSecurityRequirement

        {

            {

                new OpenApiSecurityScheme

                {

                    Reference = new OpenApiReference

                    {

                        Type = ReferenceType.SecurityScheme,

                        Id = "Bearer"

                    }

                },

                new string[] {}

            }

        });


    // 設(shè)置 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();

// 啟用身份驗(yàn)證和授權(quán)中間件

app.UseAuthentication();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>

{

    endpoints.MapControllers(); // 這里配置了使用控制器的路由

});

app.UseSwaggerUI(c =>

{

    c.SwaggerEndpoint("/swagger/v1/swagger.json", "企業(yè)官網(wǎng)Api");

    c.RoutePrefix = string.Empty; // 將 Swagger UI 設(shè)置為應(yīng)用程序的根路徑

});


ServiceLocator.Instance = app.Services;

ServiceLocator.ApplicationBuilder = app;


var db = SqlSugarHelper.Db;

//數(shù)據(jù)庫初始化

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();

接口就“勉為其難”的新建個(gè)api文件夾然后


/// <summary>

    /// 系統(tǒng)用戶

    /// </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 標(biāo)頭的值

            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 進(jìn)行其他操作


                return Success($"當(dāng)前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();

            // 驗(yàn)證用戶名和密碼


            if (!loginResult)

            {

                return Error("賬號密碼錯(cuò)誤");

            }


            // 生成 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 });

        }

    }

到這里,基本上已經(jīng)結(jié)束了,剩下的無非加加業(yè)務(wù),或者加一些更豐富的組件,什么autofac啦,nacos啦,yarp啦,seq啦

總結(jié)

對項(xiàng)目而言

其實(shí)這種方式已經(jīng)足夠適用絕大多數(shù)中小公司的普通項(xiàng)目需求了,如果你還要加些限流或者什么中間件的話,也是可以很直觀的去加,而不是像某些框架封裝一坨又一坨,你在哪加個(gè)什么東西要翻找半天,毀壞了原本dotNet自身的生態(tài)(指官方文檔)

這樣出來對的項(xiàng)目也很直觀,物盡其才,只要后續(xù)開發(fā)定好一個(gè)規(guī)范管理,就不會(huì)像你公司那破框架一堆密密麻麻的東西都沒使用過的情況出現(xiàn)

對新手而言

同時(shí)呢,這樣構(gòu)建一個(gè)項(xiàng)目框架,也方便新手學(xué)習(xí),因?yàn)槭值闹庇^,不會(huì)對莫名其妙出現(xiàn)的東西感覺到匪夷所思,根本不知道拿來做什么的,像這樣需要什么加什么,就對所有加的東西包括nuget包,中間件,或者封裝啥的都有個(gè)很清晰的認(rèn)知

對轉(zhuǎn)行到.Net的人而言

dotnet官方本身已經(jīng)是一個(gè)大封裝了,不要把別的語言思維帶到這里,做什么破功能都要自己寫,寫又寫不好,寫好了又沒文檔,人走了之后又坑公司又坑其他.net開發(fā)者

結(jié)語,給所有中小公司和個(gè)人的開發(fā)建議

馬上2024了,.Net的生態(tài)已經(jīng)算是十分豐富了,請不要再試圖自行造輪子

舉個(gè)例子假如你要
對接微信(企業(yè)微信,小程序,公眾號)/字節(jié)用這個(gè):https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat

別在那自己瞎琢磨封裝,對個(gè)人而言你瞎封裝有什么用對你也沒什么好處費(fèi)時(shí)費(fèi)力,還封裝不好,你能保證自己封裝完了還會(huì)提供詳細(xì)的文檔?

一句很重要的話,我在一線開發(fā)從curd干到框架,我覺得很多人都沒意識到的一點(diǎn)就是:
企業(yè)的項(xiàng)目,技術(shù)方面所有都要為了實(shí)際業(yè)務(wù)而做出努力,而不是為了技術(shù)而技術(shù)。

就剛才這封裝的例子,如果你是自己封裝,隨便有點(diǎn)變動(dòng)你是不是要拋下業(yè)務(wù)需求不管去維護(hù)?
一切的代碼和封裝前提思想就是不要為了寫代碼而去寫代碼,唉,忍不吐槽一下,這其實(shí)是碼農(nóng)基本素養(yǎng),但還是看的太多太心累

代碼文件補(bǔ)充

SqlSugarHelper

public 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 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲国产精品VA在线看黑屌 | 伊人久久大香线蕉aⅴ一区 三级国产99在线 | 香蕉成年网站未满十八禁 | 人人视频久久精品视频 | 亚洲一本在线视频 | 在线观看午夜福利院视频 |