HTML+LayUI+WebApi 簡單個人小白demo教程 ----《.Net踩坑之路(二)》

来源:https://www.cnblogs.com/InsufficientLuo/archive/2020/04/28/InsufficientLuo.html
-Advertisement-
Play Games

題外話: 接上篇吧。上篇主要是介紹下LayUI的使用,太興奮手打代碼去了- -。 其實這個項目用了Unity這個IOC框架,畢竟人要有夢想。感興趣的可以自己去瞭解下,後面有機會會說說對於IOC和DI的個人拙見以及Unity的使用。 進入正題。 二.WebApi 一個有夢想的鹹魚做的一個有夢想的dem ...


題外話:

接上篇吧。上篇主要是介紹下LayUI的使用,太興奮手打代碼去了- -。

其實這個項目用了Unity這個IOC框架,畢竟人要有夢想。感興趣的可以自己去瞭解下,後面有機會會說說對於IOC和DI的個人拙見以及Unity的使用。

進入正題。


 

二.WebApi

一個有夢想的鹹魚做的一個有夢想的demo項目就需要有夢想的考慮後期維護與擴展,那麼就需要從建項目開始做好文件分類。

打開VS,選擇ASP .NET Web應用程式(.NET Framework)創建一個新的項目命名Demo,然後選擇Web Api,然後建立項目。註意看項目下有個Area的文件夾,作用呢其實就是可以區分控制器,方便管理,而且控制器名稱可以重名。

 

畢竟是個B/S項目,後臺所接收的請求都屬於http請求,要處理這些請求後臺,就會涉及到安全問題,也就是許可權問題,畢竟要有夢想,還是可以發佈上伺服器的。而這個安全問題並不是只用用戶登錄驗證就能解決的,這時候就會涉及到許可權問題,參考淘寶,你可以隨意瀏覽,但是一些額外操作則需要登錄。

所以這裡我是考慮FormsAuthenticationTicket身份驗證配合授權屬性AuthorizeAttribute。

Ticket,顧名思義,想入場看比賽是需要門票的,那麼想進入自己的網站或者有資料庫操作時,我們可以為用戶設置門票。

進而小朋友些許問號,演唱會門票還有前排後排區別,考慮到實際應用情況,我們是否也需要對於用戶進行許可權區分,這樣比較符合實際情況?這樣是否更靈活?用戶與角色都能去控制

Controller的許可權是否更科學?沒錯,尤其是MVC項目,但是這裡先不考慮這麼多,我們後臺只提供介面服務。這裡我只是提供一個思路,因為要做一個大度的人,只要人進得來,場地自由活動好吧。(就是懶~)

所以會需要使用到授權屬性AuthorizeAttribute類。

  • AuthorizeAttribute

AuthorizeAttribute類是.Net Framework框架下提供寫好的一個類,Authorization(授權)屬於過濾器的一種。

這裡可以提下當引用AuthorizeAttribute類時方法的執行過程。當給某一個 Controller 指定一個許可權認證特性後,當程式需要調用這個Controller時,會先進入namespace為System.Web.Http的AuthorizeAttribute公共類,而後首先會執行AuthorizeAttribute 中的 OnAuthorization 方法,在 OnAuthorization 函數的執行過程中,如果驗證失敗了,系統會調用 HandleUnauthorizedRequest方法來進行處理,基於此原理,我們可以重寫這兩個方法,然後自定義自己的AuthorizeAttribute。而如果想提供匿名訪問服務,即調用Controller時不進入AuthorizeAttribute,它提供了AllowAnonymousAttribute屬性,字面意思也知道。

基於上述的執行過程,既然是虛函數,我們重寫他的兩個主要方法。

首先,新建文件夾Filter,文件夾下新建一個繼承於AuthorizeAttribute的類,以XXAuthorizeAttribute命名,XX則就是自定義的特性名稱。我這裡是ApiAuthorizeAttribute。

 首先重寫OnAuthorization(HttpActionContext actionContext)。

    /// <summary>
    /// api許可權特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)]
    public class ApiAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            var authorization = actionContext.Request.Headers.Authorization;

            if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0
                || actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>(true).Count != 0)
            {
                base.OnAuthorization(actionContext);//正確的訪問方法
            }
            else
            {
                if (authorization != null && authorization.Parameter != null)
                {this.HandleUnauthorizedRequest(actionContext);//沒有許可權
                }
                else
                {
                    this.HandleUnauthorizedRequest(actionContext);//沒有許可權
                }
            }
        }

        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            base.HandleUnauthorizedRequest(actionContext);
        }
    }

梳理下邏輯:

首先,通過HttpActionContext 獲得我們在ajax中傳入的Requset.Headers.Authorization.

然後,通過判斷是否有AllowAnonymousAttribute標識。

結合實際場景來理解這一步,還是上文例子。我總不可能一個演唱會主角還沒進場就給保全攔著了要我出示票據???我自己唱歌難道還要自己出錢買票欸?好氣哦是不是?

是的,如果你是保全你就被噴了,那一樣的,如果你是這個項目的開發者,整個項目運行起來就沒一個人能登錄進來,連你自己都進不去,所以考慮實際開發不要反人類邏輯思考,那麼就提供了AllowAnonymousAttribute。通過在控制器上加上[AllowAnonymous],相當於走綠色通道不要門票,那麼這個最應該放在哪呢?

如果沒有關係走不了後門,那麼就老實判斷有無門票。

然後如果沒有,保全趕人,也就是進入HandleUnauthorizedRequest方法,這是會直接將頁面重定向到登錄頁面。當然你要是宅心仁厚是個文化人,不想要保全如此粗魯,自己重寫代碼

返回一段現在最流行的Json數據問問施主可還有其他訴求。

這裡就會涉及到一個問題,WebApi的返回值是不支持的Json格式的,如果又不想更改配置,那麼可以利用HttpResponseMessage返回Json。

return new HttpResponseMessage()
            {
                Content = new StringContent("string", Encoding.UTF8, "application/json"),
            };

 這一步做完,是不是覺得終於可以進行激動人心的登錄儀式了?

想什麼呢,什麼都沒有。資料庫你都沒有呢朋友。建庫建表都還沒進行呢。

  • ORM
  • Entity Framework

Object Relational Mapping,對象關係映射。

這個內容很多,這裡使用Entity Framework,畢竟.Net一套。至於為什麼,最直接的就是因為不想寫SQL語句而且安全,這理由還不充分嗎?不行你往你自己用SQL語句寫的登錄網站試試輸入' or 1 = 1 --',看看會不會有驚喜?有驚喜的少年恭喜你真的很適合看我的博客,給個關註給個推薦謝謝嗷。

下個定義:EF是微軟基於ADO .Net而開發的一套跨資料庫的ORM框架(hhhhhh這裡就不做過多贅述了,資料很多,我自己也寫了一個Word文檔,如果全小白自學的可以聯繫我發給你哈哈哈,其實後面會單獨寫EF的,還會淺談下自學的Entity Framework Core,畢竟我也很菜)

在解決方案Demo下建立Data文件夾,文件夾下新建一個.Net Frameworek的類庫,取名Domain,Domain類庫下建立Models文件夾,此文件夾下建立實體類。

建庫建表時就要考慮到項目需求問題,這點很重要很重要很重要,這也時有無項目經驗的主要體現。加粗加紅好了。

因為是個簡單教程,那麼我這個項目,目前先做個做個能給每個公司提供管理員工,管理自己公司信息報表的簡單平臺。後期縱向橫向發展那些再說。比如加個department表之類的,然後再來個上級管理,下級官吏啊嘖嘖嘖,少年自己沖。

我們先建立簡單的三張表,一張員工表,提供賬號密碼以及簡單個人信息問題。一張賬號信息表,方便記錄一些賬號操作行為。一張公司表,提供基礎信息。

公司與員工的關係,員工與賬號的關係,設置一個公司有一個管理賬號,那麼又有

建表時,考慮到更新性原因,儘量不適用外鍵,所有依賴關係通過自己去思考,比如賬號信息表是不是應該有個用戶ID欄位,以便於進行聯表操作之類,同時對於刪除問題,可以根據不同情景,去考慮使用物理刪除還是邏輯刪除。

這裡簡單提下物理刪除和邏輯刪除的區別:物理刪除是刪除資料庫中的數據,不具有恢復性。而邏輯刪除,不刪除資料庫中的數據,而是通過一些自定義的Flag去判斷,可以理解為黑名單,你可以表格中設置bool 類型欄位deleteSian,為true時可以使用,為false時拉黑,禁用,當需要時可以解除拉黑。

EmployeeModel類: 

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Demo.Domain.Models
{
    [Table("EmployeesInfo")]
    public class EmployeesInfoModel
    {
        [Key]
        public int EmployeesID { get; set; }
        public int CompanyID { get; set; }
        /// <summary>
        /// 員工姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 性別
        /// </summary>
        public string Sex { get; set; }
        /// <summary>
        /// 工號
        /// </summary>
        public string JobNumber { get; set; }
        /// <summary>
        /// 員工電話
        /// </summary>
        public string Mobile { get; set; }
        /// <summary>
        /// 賬號
        /// </summary>
        public string AccountNum { get; set; }
        /// <summary>
        /// 密碼
        /// </summary>
        public string PassWords { get; set; }
        /// <summary>
        /// 賬號身份
        /// </summary>
        public int AccountRole { get; set; }
        /// <summary>
        /// 員工職位
        /// </summary>
        public int EmployeeRole { get; set; } 
        public bool deleteSign { get; set; }
    }
}

 AccountInfoModel類:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Demo.Domain.Models
{
    [Table("AccountInfo")]
    public class AccountInfoModel
    {
        [Key]
        public int AccountID { get; set; }
        /// <summary>
        /// 賬號名
        /// </summary>
        public string AccountName { get; set; }
        public int EmployeesID { get; set; }
        /// <summary>
        /// 管理查詢
        /// </summary>
        public int CompanyID { get; set; }
        /// <summary>
        /// 登陸次數
        /// </summary>
        public int LoginCount { get; set; }
        /// <summary>
        /// 開號時間
        /// </summary>
        public DateTime? CreateTime { get; set; }
        public string CreateIP { get; set; }
        /// <summary>
        /// 最後登陸時間
        /// </summary>
        public DateTime? LastLoginTime { get; set; }
        public string LastLoginIP { get; set; }
    }
}

CompanyInfoModel類:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Demo.Domain.Models
{
    [Table("CompanyInfo")]
    public class CompanyInfoModel
    {
        /// <summary>
        /// 編號
        /// </summary>
        [Key]
        public int CompanyID { get; set; }
        /// <summary>
        ////// </summary>
        public string Province { get; set; }
        /// <summary>
        ////// </summary>
        public string City { get; set; }
        /// <summary>
        ////// </summary>
        public string Area { get; set; }
        /// <summary>
        /// 全稱
        /// </summary>
        public string FullName { get; set; }
        /// <summary>
        /// 組織機構代碼
        /// </summary>
        public string Organizationcode { get; set; }
        
        public string Mobile { get; set; }

        public int Power { get; set; }

        public bool deleteSign { get; set; }
    }

    /// <summary>
    /// 管理範圍
    /// </summary>
    //public enum Power
    //{
    //    全部 = 0,
    //    多區 = 1,
    //    單區 = 2
    //}
    ///// <summary>
    ///// 賬號身份
    ///// </summary>
    //public enum AccountRole
    //{
    //    管理登錄 = 0,
    //    普通登錄 = 1
    //}
    ///// <summary>
    ///// 員工身份
    ///// </summary>
    //public enum EmployeeRole
    //{
    //    部門主管 = 0,
    //    普通員工 = 1
    //}
}

 也可以使用枚舉,這裡我還是沒用了。但是意思就是這麼個意思哈哈哈哈。

 

通過EF建庫建表完成之後,是不是覺得終於可以進行激動人心的登錄儀式了?

對的,沒錯。

 

但是,

最近忙,餓了,回家做飯。下回分解。逃。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄 pyecharts模塊 簡介 Echarts 是一個由百度開源的數據可視化,憑藉著良好的交互性,精巧的圖表設計,得到了眾多開發者的認可。而 Python 是一門富有表達力的語言,很適合用於數據處理。當數據分析遇上數據可視化時,pyecharts 誕生了。 如果想要掌握pyecharts,可以閱 ...
  • 最近在項目中遇到一個需要用線程池來處理任務的需求,於是我用 來實現,但是在實現過程中我發現提交大量任務時它的處理邏輯是這樣的(提交任務還有一個 方法內部也調用了 方法): java public void execute(Runnable command) { if (command == null ...
  • 堆記憶體常見的分配策略 針對的是Serial 加 Serial Old 客戶端預設收集器組合下的記憶體分配和回收策略 經典的垃圾收集器 CMS 收集器 CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的垃圾收集器。從名字可以看出,CMS 是基於標記-清除演算法的 ...
  • 隨著PHP7.4而來的有一個我認為非常有用的一個擴展:PHP FFI(Foreign Function interface),引用一段PHP FFI RFC中的一段描述 For PHP, FFI opens a way to write PHP extensions and bindings to ...
  • 搬運自:https://www.cnblogs.com/AlanLee/p/5329555.html 原理搜關鍵字:DFA演算法 基本照抄了原文的JAVA代碼,其中應該可以用Dictionary<string,int>來代替Hashtable,但搜到的資料都說Hashtable快得要命,雖然知道他們說 ...
  • 前言 CQRS ( Command Query Responsibility Segregation )命令查詢職責分離模式,它主要從我們業務系統中進行分離出我們(Command 增、刪、改)和(Query 查), 同時他可以明確的區分我們每一個動作向我們的請求模型和響應模型.從而降低了我們系統的復 ...
  • [TOC] 上一篇,我們學習了任務的基礎,學會多種方式場景任務和執行,非同步獲取返回結果等。上一篇講述的知識比較多,這一篇只要是代碼實踐和示例操作。 判斷任務狀態 | 屬性 | 說明 | | | | | IsCanceled | 獲取此 Task 實例是否由於被取消的原因而已完成執行。 | | IsC ...
  • 是否能編譯一個exe , 又能啟動 Asp.Net Core , 又能自帶最新版的Chromium瀏覽器 , 自己瀏覽自己? 這裡給出了一個最簡單的C#/C++整合CEF框架的方式和詳細步驟. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...