公交车上荫蒂添的好舒服的电影-公用玩物(np双xing总受)-公用小荡货芊芊-公与妇仑乱hd-攻把受做哭边走边肉楼梯play-古装一级淫片a免费播放口

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

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

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

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


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

前提

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

方式

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

官方路子

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

我的野路子

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

模擬前提場(chǎng)景

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

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

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

  • 需要swagger文檔

  • 需要上傳文件

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

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

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

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

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

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

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

代碼

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

Program.cs 里面直接無(wú)腦寫下以下代碼

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ù)庫(kù)初始化

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>

        /// 檢測(cè)Token信息

        /// </summary>

        /// <returns></returns>

        [HttpGet]

        [Authorize]

        public ApiResult CheckToken()

        {


            var httpContext = HttpContext;


            // 從請(qǐng)求頭中獲取 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("賬號(hào)密碼錯(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é)束了,剩下的無(wú)非加加業(yè)務(wù),或者加一些更豐富的組件,什么autofac啦,nacos啦,yarp啦,seq啦

總結(jié)

對(duì)項(xiàng)目而言

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

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

對(duì)新手而言

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

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

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

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

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

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

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

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

主站蜘蛛池模板: 国产一区二三区 | 国产精品午夜自在在线精品 | 99精品国产高清一区二区麻豆 | 国产成人精品 | 精品视频免费日产一区 | 国产精品经典三级一区 | 国产成人av一区二区三区在线 | 成人毛片无码一区二区三区 | 国产高清精品一区 | 国产a视频的魅力与发展现状 | 国产边按摩边被躁在线播放 | 2025国产精品自拍 | 国产精品成人久久电影 | 成人国产一区二区三区久久久 | 高清在线精品一区二区三区 | 精品一区二区国产偷窥 | 成人午夜福利免费无码视频 | 国产在线拍揄自揄视精品 | 国产精品丝袜久久久久久不卡 | 国产丝袜视频一区二区三区 | 91精品人成在线观看 | 精品精品国产欧美在线 | 国产精品偷伦视频观看免费 | 国产欧美另类精品又又久久 | 国产精品亚洲精品一区二区 | 国产欧美日韩免费观看一区二区 | 高潮国产精品一区二区 | 国产精品欧美亚洲日韩国产 | 91亚洲中文天堂 | 国产一区二区三区亚洲 | 99国产精品视频一区二区三区 | 国产无码午夜不卡 | 国产在线拍揄自揄视精品不卡 | 国产成人18黄网站在线观看 | 91午夜福利在线观看精品 | 丰满人妻系列无码专区 | 国产巨臀系列在线观看 | 国产在线观看大量精品福利 | 国产精彩视频一区二区三区 | 国产女人喷潮视频在线观看 | 国产免费理论片 |