004_URL 路由 - URL 路由

来源:http://www.cnblogs.com/KeSaga/archive/2016/06/01/5550033.html
-Advertisement-
Play Games

在Web Form 情況下,每一個 ASPX頁面既是一個文件,又是一個隊請求自包含的響應。而在 MVC 情況下,請求是由控制器類中的動作方法處理的,而且與硬碟上的文件沒有一對一的相互關係。 ASP.NET 平臺為了處理 MVC 的 URL,採用了路由系統,它主要有兩個功能: 考查一個輸入 URL(I ...


  在Web Form 情況下,每一個 ASPX頁面既是一個文件,又是一個隊請求自包含的響應。而在 MVC 情況下,請求是由控制器類中的動作方法處理的,而且與硬碟上的文件沒有一對一的相互關係。

ASP.NET 平臺為了處理 MVC 的 URL,採用了路由系統,它主要有兩個功能:

  • 考查一個輸入 URL(Incoming URL),並推出該請求想要的是哪一個控制器和動作。這正是接收到一個客戶端請求時,希望路由系統去做的事情。
  • 生成一個輸出 URL(Outgoing URL),這些 URL 是在視圖渲染的 HTML 中出現的 URL,以便使用戶點擊這些鏈接時,調用一個特定的動作(此時,它又變成了輸入 URL)。

URL 模式

  路由系統用一組路由來實現它的功能。這些路由共同組成了應用程式的URL架構(Schema)或方案(Scheme),這種URL架構(或方案)是應用程式能夠識別並能對之作出相應的一組URL。

  每一條路由都包含一個URL模式(Pattern),用它與一個輸入的URL進行比較,如果該模式與這個URL匹配,那麼它(URL模式)便被路由系統用來對這個URL進行處理。

  URL模式主要有連個關鍵行為:

  • URL 模式是保守的(Conservative):只匹配與模式具有相同片段數的URL。
  • URL模式是寬鬆的(Liberal):如果一個URL正好具有正確的片段數,該模式就會用來為片段變數提取值,而不管這個值可能是什麼。

  如示例:

http://mysite.com

/Admin

/Index

 

First Segment

Second Segment

 

片段1

片段2

簡單路由的創建及註冊

   定義路由的文件 RouteConfig.cs 文件是在 App_Start 文件夾中的。在其中定義的靜態 RegisterRoutes 是通過 Global.asax.cs 文件進行調用的,當啟動應用程式時,它建立了一些核心的 MVC 特性。

         基本流程如下:

         底層的 ASP.NET 平臺在 MVC 第一次啟動時調用Global.asax.cs —>Application_Start() ——> RouteConfig.cs—> RegisterRoutes()。

         定義函數類似如下樣子:

        public static void RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 

            routes.MapRoute(

                name: "Default",

                url: "{controller}/{action}/{id}",

                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

            );

        }

         Global.asax.cs中的Application_Start()函數調用方式如下方式:

RouteConfig.RegisterRoutes(RouteTable.Routes);

         註冊路由的一個方便的方法是,使用 RouteCollection 類所定義的MapRoute方法。如:

routes.MapRoute("MyRoute", "{controller}/{action}");

         也可以通過創建一個新的 Route 來實現,如:

Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler());

    routes.Add("MyRoute", myRoute);

   上述兩種方式的效果是一樣的。

定義預設值

  預設URL被表示成“~/”送給路由系統。由於URL模式是保守的(即它們只匹配指定片段數的URL),如果要改變這種預設行為,則需要使用預設值——當URL不包含與一個片段匹配的值時,便使用預設值。如下麵粗體字部分:

    public class RouteConfig

    {

        public static void RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 

            routes.MapRoute(

                name: "Default",

                url: "{controller}/{action}/{id}",

                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

            );

 

            // 通過創建一個新的 Route 實現路由的註冊

            //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler());

            //routes.Add("MyRoute", myRoute);

 

            // 使用 RouteCollection 類所定義的MapRoute方法實現路由的註冊(效果與上面方式相同)

            // 下麵第三個參數提供了一個包含預設路由的值的對象,當 URL 片段無匹配的值時(如片段少於定義給定的片段數時),

            // 便會使用預設值(片段數需要符合定義的路由片段數,太多時將不做匹配)。

            routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" });

 

        }

    }

 

使用靜態URL片段

   1、有時我們不僅需要URL模式的所有片段都是可變的,也會需要創建具體靜態片段的模式。比如當我們需要支持帶有某種首碼的URL,例如帶有Public首碼的URL:http://mydomain.com/Public/Home/Index。

   如:routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" });

         上面這句話的意思是:將匹配具有三個片段的URL,但第一個必須是Public,其他兩個片段可以有任何值,並將被用於controller和action變了。如果沒有後兩個片段,則將使用預設值。

         2、可以創建一個既有靜態也有可變元素片段的 URL 模式,如:

 

            // 創建一個既有靜態也有可變元素片段的 URL 模式

            // MapRoute 將在路由集合的末尾添加一條新的路由

            // 該路由需要放在其他路由之前,原因是路由是按照他們在 RouteCollection 對象中出現的順序被運用的。

            // 我們可以將一條路由按照指定的位置添加,但一般不採用這種方式,原因是讓路由以它們被定義的順序來

            // 運用更容易理解運用於一個應用程式的路由。

            // 因此,路由系統是先匹配最前面定義的路由,如果不能匹配,則繼續下一個,所以,最好先定義較具體的路

            // 由,然後次之,以此類推。

            routes.MapRoute("", "X{controller}/{action}");

 

 

         假設如下顛倒順序:

routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" });

routes.MapRoute("", "X{controller}/{action}");

         那麼,第一條路由匹配任何具有0、1、2片段的URL,它將是被使用的一條。更具體的路由現在是列表的第二條,它將是不可到達的。新路由(第二條)去掉URL的前導“X”,但舊路由(第一條)卻不會這麼做。因此,像這樣的一條URL:

http://mydomain.com/XHome/Index

         將以名為“XHome”的控制器為目標,而這是不存在的,因此會導致一個“404——未找到”錯誤被髮送給用戶。

         3、使用靜態片段和預設值為特定的路由創建一個別名

         如果已經公開發佈了URL方案,並且它與用戶形成了一種契約,此時創建別名是有用的。如果我們重構程式,則需要保留以前的URL格式。下麵示例給出瞭如何保留舊式URL方案的路由:

            // 結合靜態片段和預設值為特定的路由創建一個別名

            // 匹配第一個片段是 Shop 的任意兩片段 URL,action 的值取自第二個 URL 片段。

            // 由於此 URL 模式未提供 controler 的可變片段,所以會使用提供的預設值(“Home”)。即對

            // Shop 控制器上的一個動作的請求會被轉換成對 Home 控制器的請求。

            routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" });

         如果更徹底的,我們可以為被重構且不再出現在控制器中的動作方法創建別名,如下:

            routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" });

 

定義自定義片段變數

   在MVC中有三個片段變數的名稱是被保留的,不能用於自定義片段變數名,除此之外均可命名為自定義片段變數。這三個片段變數分別是:controller(控制器片段變數)、action(動作方法片段變數)和area(區域片段變數)。

   自定義片段變數示例:

        // 定義一個名為“id”的自定義變數(粗體字部分)。如果沒有與之對應的片段內容,則將使用預設值

        routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "DefaultId" });


         我們可以在動作方法中通過RouteData.Values屬性訪問任何一個片段變數。如下:

        /// <summary>

        /// 獲取 URL 模式中自定義變數(“id”)的值,並用 ViewBag 將它傳遞給視圖。

        /// </summary>

        /// <returns></returns>

        public ActionResult CustomVariable()

        {

            ViewBag.Controller = "Home";

            ViewBag.Action = "CustomVariable";

            ViewBag.CustomVariable = RouteData.Values["id"];

            return View();

        }

 

用自定義變數作為動作方法參數

  在開發過程中除了可以使用RouteData.Values屬性訪問自定義路由變數,還可以以URL模式中的變數相匹配的名稱,來定義動作方法的參數。此時,MVC框架將把從URL獲得的值作為參數傳遞給動作方法。

  如下麵的寫法:

        /// <summary>

        /// 用自定義變數作為動作方法參數

        /// </summary>

        /// <param name="id">

        /// MVC 框架會嘗試將 URL 的值轉換成所定義的參數類型,這

        /// 里將轉換成 string ,MVC 框的這以特性將方便開發者不必

        /// 自行做轉換。

        /// </param>

        /// <returns></returns>

        public ActionResult CustomVariable(string id)

        {

            ViewBag.Controller = "Home";

            ViewBag.Action = "CustomVariable";

            ViewBag.CustomVariable = id;

            return View();

        }


 

定義可選URL片段

   可選URL片段是指用戶不需要指定、但又未指定預設值的片段。

         下麵示例通過將預設值設置為“UrlParameter.Optional”,便指明瞭一個片段變數是可選的。在下麵實例中,只有當輸入URL中存在相應片段時,id變數才被添加到變數集合中,當未為可選片段變數提供值時,對應的參數值將為null

            // 定義可選 URL 片段。該路由的效果是:無論是否提供id,都將進行匹配

            routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });

   對應的動作方法如下:

        public ActionResult CustomVariable(string id)

        {
            ViewBag.Controller = "Home";
            ViewBag.Action = "CustomVariable";
            // 檢查是否為一個可選片段變數提供了值
            ViewBag.CustomVariable = id == null ? "<no value>" : id;
            return View();
        }

註:該動作方法可以通過C#的可選參數的方式實現將片段變數的預設值從路由中分離,詳見使用可選URL片段強制關註分離

  • 使用可選URL片段強制關註分離

   使用C#的可選參數及路由中的可選片段變數定義動作方法參數的預設值,以實現將片段變數的預設值從應用程式的路由中分離。如:

       

     /// <summary>

        /// 使用 C# 的可選參數為動作方法參數定義預設值

        /// </summary>

        /// <param name="id"></param>

        /// <returns></returns>

        public ActionResult CustomVariable(string id = "DefaultId")

        {

            ViewBag.Controller = "Home";

            ViewBag.Action = "CustomVariable";

            ViewBag.CustomVariable = id;

            return View();

        }

         與之對應的可選URL片段路由就是前面介紹過的“可選URL片段”(通過將預設值設置為UrlParameter.Optional來實現)。其效果與這條路由相同:routes.MapRoute("MyRoute", "{controller}/{action}/{id}",new { controller = "Home", action = "Index", id = "DefaultId" });。

定義可變長路由

   通過指定“全匹配(catchall)”片段變數,並以星號(*)為首碼,便可以實現一個可變長路由。如:

            // 定義可變長路由

            routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",

                new { controller = "Home", action = "Index", id = UrlParameter.Optional });

       上述代碼中,斜體的片段變數定義中,前三個分別用於設置controller、action和id的值,後面的加粗斜體({*catchall})實現了可變長路由的定義,可以匹配任何URL,無論有多少片段,也不管其值是什麼。

       由於由catchall捕獲的片段是以“片段/片段/片段”的形式表示的,因此,需要對這個字元串進行處理——將其分解成一個個的片段,在處理catchall變數時和處理自定義變數是一樣的,只是需要註意該變數的值可能是多個片段連成的一個單一的字元串,就像前面說的那種形式,當然是不需要擔心字元串中會存在前導或後導的“/”字元。

按命名空間區分控制器優先順序

         如果在不同的命名空間存在同名控制器時,MVC框架將不知道該如何處理,即對象不明確。

         假設在示例項目中添加名為AdditionalControllers的文件夾,並添加一個新的Home控制器,如下所示:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

 

namespace UrlsAndRoutes.AdditionalControllers

{

    public class HomeController : Controller

    {

        public ActionResult Index()

        {

            ViewBag.Controller = "Additional Controllers - Home";

            ViewBag.Action = "Index";

            return View("ActionName");

        }

 

    }

}


         此時,運行程式,將會出現錯誤,原因就是在不同的命名空間下存在同名控制器,而MVC不會處理這種問題。但是,可以通過將這些命名空間表示成一個字元串數組的方式通知MVC框架要對指定的命名空間優先進行處理。如:

        public static void RegisterRoutes(RouteCollection routes)
        {

            // 指定命名空間解析順序,MVC 將在處理其他命名空間之前優先處理 UrlsAndRoutes.AdditionalControllers 命名空間

            routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",

                new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new string[] { "UrlsAndRoutes.AdditionalControllers" });
        }

 

         如果要對一個命名空間的某個控制器給予優先,但又要解析另一個命名空間中的所以其他控制器,就要創建多條路由,原因是添加到一條路由的同一組字元串數組中的命名空間具有同等的優先順序。如:

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("AddControllerRoute", "{controller}/{action}/{id}/{*catchall}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                new string[] { "UrlsAndRoutes.AdditionalControllers" });
            routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                new string[] { "UrlsAndRoutes.Controllers" });

        }

         當明確請求第一個片段為Home的URL時,會運用第一條路由,並且會以AdditionalControllers文件夾中的Home控制器為目標。其他所有請求,包括未指定第一片段的那些請求,會由Controllers文件夾中的控制器處理。

         當然,也可以通知MVC框架只處理指定的命名空間。如果沒有匹配的控制器,將不會查找其他命名空間下的控制器。如:

        public static void RegisterRoutes(RouteCollection routes)
        {
            // 禁用備用命名空間
            Route myRoute = routes.MapRoute("AddControllerRoute", "{controller}/{action}/{id}/{*catchall}",
                  new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                  new string[] { "UrlsAndRoutes.AdditionalControllers" });
            myRoute.DataTokens["UseNamespaceFallback"] = false;

        }

         為了禁止搜索其他命名空間的控制器,必須取得這個Route對象,並把DataTokens屬性集中的UseNamespaceFallback鍵值設置為“false”。其效果是,不能滿足AdditionalControllers文件夾中Home控制器的請求將失敗。

約束路由

用正則表達式約束路由

        /// <summary>
        /// 使用正則表達式約束一條路由
        /// </summary>
        /// <param name="routes"></param>
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
                  new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                  new { controller = "^H.*" },
                  new string[] { "UrlsAndRoutes.Controllers" });

        }

         通過把約束作為參數傳遞給MapRoute方法,可以定義約束。約束被表示成一個匿名類型,該類型的屬性對應於想要進行約束的片段變數名。

         註意,在執行時,預設值是在約束被檢測之前運用的。也就是說在匹配預設值的情況下,先匹配預設值,然後再進行約束的檢查。

將一條路由約束到一組指定的值

如果想限定URL片段只匹配一些指定的值,則可以通過豎線(|)字元來實現,如:

        /// <summary>
        /// 將一條路由約束到一組指定的值
        /// </summary>
        /// <param name="routes"></param>
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
                  new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                  new { controller = "^H.*", action = "^Index$|^About&=$" },
                  new string[] { "UrlsAndRoutes.Controllers" });

        }

         這條約束合起來就是施加於action變數值的約束與施加於controller變數的約束相組合。它只匹配這樣的URL:controller變數以“H”字母打頭,而且action變數是“Index”或“About”。

使用HTTP方法約束路由

   可以對路由進行以使他們只匹配指定的HTTP方法進行請求的URL。如:

        /// <summary>
        /// 基於 HTTP 方法進行路由的約束
        /// </summary>
        /// <param name="routes"></param>
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
                  new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                  new { controller = "^H.*", action = "Index|About",
                      httpMethod = new HttpMethodConstraint("GET") },
                  new string[] { "UrlsAndRoutes.Controllers" });
        }

         可以像下麵的方式方便的添加對HTTP其他方法的支持。如:

httpMethod = new HttpMethodConstraint("GET","POST")

定義自定義約束

   可以通過實現IRouteConstraint介面,來定義自己的自定義約束。如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;

namespace UrlsAndRoutes.Infrastructure
{
    public class UserAgentConstratint : IRouteConstraint
    {

        private string _requiredUserAgent;

        public UserAgentConstratint(string agentParam)
        {
            _requiredUserAgent = agentParam;
        }

        public bool Match(HttpContextBase httpContext
            , Route route
            , string parameterName
            , RouteValueDictionary values
            , RouteDirection routeDirection)
        {
            return httpContext.Request.UserAgent != null && httpContext.Request.UserAgent.Contains(_requiredUserAgent);
        }

    }
}

         IRouteConstraint介面定義了Match方法,實現它可以用了實現對路由系統只是它的約束是否已得到滿足。其中參數提供了這些對象的訪問:客戶端請求、待評估路由、約束的參數名、從URL提取的片段變數,以及該請求要檢查的是輸入URL還是輸出URL的細節。上述自定義約束的使用方式見下列代碼:

        /// <summary>
        /// 自定義路由約束的使用
        /// </summary>
        /// <param name="routes"></param>
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("ChromeRoute", "{*catchall}",
                  new { controller = "Home", action = "Index" },
                  new
                  {
                      customConstraint = new UserAgentConstratint("Chrome")
                  },
                  new string[] { "UrlsAndRoutes.AdditionalControllers" });

            routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
                  new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                  new string[] { "UrlsAndRoutes.Controllers" });
        }

   上例的約束的作用是:第一條約束路由時期只匹配來自用戶代理字元串含有Chrome的瀏覽器的請求。如果此路由匹配,那麼該請求將被髮送給AdditionalControllers文件夾中定義的Home控制器的Index動作方法,而不管所請求的URL具有什麼樣的結構或內容。第二條路由將匹配其他所有請求,並以Controllers文件夾中的控制器為目標。

   最終的效果是Chrome瀏覽器最終只能訪問應用程式的同一個位置。需要註意的是不建議對應用程式進行限制,以使他只支持一種瀏覽器,該示例只是提供了一種得到有關字母的辦法。同時,該示例只是為了演示自定義路由約束。


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

-Advertisement-
Play Games
更多相關文章
  • 1.SQL註入:SQL註入攻擊是web應用程式的一種安全漏洞,可以將不安全的數據提交給運用程式,使應用程式在伺服器上執行不安全的sql命令。使用該攻擊可以輕鬆的登錄運用程式。 例如:該管理員賬號密碼為xiexun,該sql的正確語句應該為: 如果在沒有做任何處理的情況下,在登錄名文本框中輸入(xux ...
  • 常用快捷鍵 自動生成頭部註釋 代碼片段 NuGet Team Foundation 常用的VS快捷鍵 查看與設置快捷鍵 一般在菜單裡面我們直接就可以看到一些功能的快捷鍵。另外,可以依次通過 菜單欄-工具-選項-環境-鍵盤 中查看和設置對應功能的快捷鍵 推薦幾個我比較常用的快捷鍵 我用的是VS2015 ...
  • 1、頁面後臺代碼添加如下靜態變數: 2、在處理數據的開始,初始化total和startTime變數: 3、在處理數據過程中,不斷累加cur: 4、前端每隔200毫秒獲取進度: 5、後臺計算進度: 效果圖(文字錯了,不是“導入進度”,而是“數據處理進度:”): ...
  • 公司業務量比較大,接了很多項目,為了縮短開發周期老闆讓我牽頭搭建了一個敏捷開發框架。 我們主要的業務是做OA、CRM、ERP一類的管理系統,一個通用的後臺搭出來,再配合一些快速開發的組件開發效率能提高很多。 另外老闆一再強調要支持APP開發,一次開發能部署到安卓和IOS上。 作為開篇之作,先介紹一下 ...
  • 定製路由系統 路由系統是靈活可配置的,當然還可以通過下麵這兩種方式定製路由系統,來滿足其他需求。 1、 通過創建自定義的RouteBase實現; 2、 通過創建自定義路由處理程式實現。 創建自定義的RouteBase實現 創建自定義的RouteBase實現,需要實現一個RouteBase的派生類,而 ...
  • 同Winsock1相比,Winsock2最明顯的就是支持了Raw Socket套接字類型,使用Raw Socket,可把網卡設置成混雜模式,在這種模式下,我們可以收到網路上的IP包,當然包括目的不是本機的IP包,通過原始套接字,我們也可以更加自如地控制Windows下的多種協議,而且能夠對網路底層的 ...
  • 在上一篇文章中我們主要分析了ASP.NET Core預設依賴註入容器的存儲和解析,這一篇文章主要補充一下上一篇文章忽略的一些細節:有關服務回收的問題,即服務的生命周期問題。有關源碼可以去GitHub上找到。 這次的主角就是ServiceProvider一人,所有有關生命周期的源碼幾乎都集中在Serv ...
  • 相信很多人用過MessageBox.show(),是不是覺得這個消息框有點醜呢,反正我是覺得有點醜的,所以我自己重寫了一個。先不說,上兩幅圖對比先: 當然,也不是很好看,不過比原有的好多了。 不多說了,先上xmal代碼: 1 <Window x:Class="MESBox.MEGBox" 2 xml ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...