ASP .Net Core路由(Route) - 紙殼CMS的關鍵

来源:https://www.cnblogs.com/seriawei/archive/2018/09/30/9732233.html
-Advertisement-
Play Games

紙殼CMS是一個開源免費的,可視化設計,線上編輯的內容管理系統。基於ASP .Net Core開發,插件式設計的CMS系統 ...


關於紙殼CMS

紙殼CMS是一個開源免費的,可視化設計,線上編輯的內容管理系統。基於ASP .Net Core開發,插件式設計:

GitHubhttps://github.com/SeriaWei/ZKEACMS.Core

路由

路由是ASP .Net裡面至關重要的一個組成部分,路由的功能簡單的說就是把用戶請求的地址“轉移”到對應的Controller,Action。而路由,也是紙殼CMS可以自定義頁面的關鍵。

在紙殼CMS中,給路由定義了優先順序,所以在處理用戶請求地址的時候,通過路由的優先順序來決定訪問的流程走向,如果找到匹配的路由,則優先走該路由對應的 Controller -> Action -> View,如果沒有匹配的路由,則走路由優先權最低“全捕捉”路由來處理用戶的請求,最後返迴響應。

優先順序最低的“全捕捉”路由是用來處理用戶創建的頁面。"{*path}",所有這些請求,都會到 PageController -> Main 進行處理。這樣就可以把原來真實的頁面,變為虛擬的,並由用戶來創建,存到資料庫中。請求流程,大致如下圖所示:

全捕捉路由和通用後臺路由的定義,Priority值越大,優先順序越高:

new RouteDescriptor
{
    RouteName = "pageRoute",
    Template = "{*path}",
    Defaults = new { controller = "Page", action = "Main" },
    Constraints = new { path = new PageRouteConstraint() },
    Priority = -1
},
new RouteDescriptor
{
    RouteName = "admin",
    Template = "admin/{controller=Dashboard}/{action=index}/{id?}",
    Defaults=new { module = "admin" },
    Priority = 10
}

PageRouteConstraint

PageRouteConstraint,這裡並不是用來約束路由的,而是在這裡處理路由數據,要在這裡構建RouteData,所以看代碼,始終是返回true。

namespace ZKEACMS
{
    public class PageRouteConstraint : IRouteConstraint
    {
        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            var value = values[routeKey];
            if (routeKey == "path" && value != null)
            {
                string path = "/" + value.ToString();

                var routeDataProviders = httpContext.RequestServices.GetService<IEnumerable<IRouteDataProvider>>();
                foreach (var item in routeDataProviders.OrderBy(m => m.Order))
                {
                    path = item.ExtractVirtualPath(path, values);
                }
                if (path.IsNullOrWhiteSpace())
                {
                    path = "/";
                }
                values[routeKey] = path;
            }
            return true;
        }
    }
}

紙殼CMS裡面使用IRouteDataProvider來自定義處理請求URL和RouteData。例如使用HtmlRouteDataProvider來實現偽靜態:

namespace ZKEACMS.Route
{
    public class HtmlRouteDataProvider : IRouteDataProvider
    {
        const string htmlExt = ".html";

        public int Order { get { return 0; } }

        public string ExtractVirtualPath(string path, RouteValueDictionary values)
        {
            if (path.EndsWith(htmlExt, StringComparison.OrdinalIgnoreCase))
            {
                path = path.Substring(0, path.LastIndexOf(htmlExt));
            }
            return path;
        }
    }
}

使用PaginationRouteDataProvider來獲取分頁數據等等:

namespace ZKEACMS.Route
{
    public class PaginationRouteDataProvider : IRouteDataProvider
    {
        public int Order { get { return 1; } }
        public string ExtractVirtualPath(string path, RouteValueDictionary values)
        {
            if (CustomRegex.PageRegex.IsMatch(path))
            {
                int page = -1;
                path = CustomRegex.PageRegex.Replace(path, evaluator =>
                {
                    int.TryParse(evaluator.Groups[1].Value, out page);
                    return string.Empty;
                });
                if (page >= 0 && !values.ContainsKey(StringKeys.RouteValue_Page))
                {
                    values.Add(StringKeys.RouteValue_Page, page);
                }                
            }
            return path;
        }
    }
}

插件里路由

每個插件都可以定義自己的路由,所以一定要處理它們的優先順序關係。定義的方式很簡單,在插件類(xxxPlug.cs)裡面,實現RegistRoute方法就可以了。例如自定義表單插件裡面的提交數據路由:

namespace ZKEACMS.FormGenerator
{
    public class FormPlug : PluginBase
    {
        public override IEnumerable<RouteDescriptor> RegistRoute()
        {
            yield return new RouteDescriptor
            {
                RouteName = "FormData",
                Template = "FormDataHandle/Submit",
                Defaults = new { controller = "FormData", action = "Submit" },
                Priority = 11
            };
        }        
    }
}

最後

紙殼CMS充分利用了路由來實現自定義頁面的功能,而路由不再單純的只有{controller}/{action}。看了紙殼CMS的路由機制,我相信你應該會有所收穫,:-),歡迎有興趣的大神們加入進來!

https://github.com/SeriaWei/ZKEACMS.Core


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

-Advertisement-
Play Games
更多相關文章
  • copyfileobj方法 將類文件對象fsrc的內容複製到類文件對象fdst 我一般的用法: 註:如果fsrc對象的當前文件位置不為0,那麼將只複製從當前文件位置到文件末尾的內容 copyfile方法 將名為src的文件的內容複製到名為dst的文件中,並返回dst。src和dst是作為字元串給出的 ...
  • 主要是實現從相機進入預覽模式,然後刪除一張相片,並檢查刪除結果 ...
  • 你一定聽說過HashSet就是通過HashMap實現的 相信我,翻一翻HashSet的源碼,秒懂!! 其實很多東西,只是沒有靜下心來看,只要去看,說不定一下子就明白了…… HashSet 兩個屬性: 所有HashSet的操作都是通過對其屬性map操作實現的,map的key是HashSet,map的v ...
  • Why? look at the following 2 pieces of code for implementing a simple web server based on socket, can you point out the problems(I put them in the com ...
  • 多態指的是允許不同類的對象對同一消息做出響應,即同一消息可以根據發送對象的不同而採用多種不同的行為方式(發送消息就是函數調用)。實現多態的方法是動態綁定( Dynamic Binding),動態綁定指的是在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。 在Java語言中, Ov ...
  • 前言 有時候必須在伺服器上調試代碼。比如做微信公眾號開發,需要做一些url回調, 此時無法在開發電腦上做調試。所以遠程調試代碼就很有必要了。經過2個小時摸索,順利實現。 (註意:用jexus時無法遠程調試,因為jexus隱藏了dotnet進程,它把dotnet作為自己的子進程,所以無法附加dotne ...
  • 一,安裝 最近在用 Visual Studio Code 學習.net core ,記錄下學習的過程,首先去官網下載最新的.net core2.1安裝包,有windows 和mac,根據自己的開發環境而定。如下圖,剛安裝完成並不是這樣的,需要在擴展 Ctrl+Shift+X 中安裝漢化包, Wind ...
  • 概述Visual studio 項目允許在項目屬性生成事件一欄中指定預先生成和後期生成事件來實現項目生成與部署的自動化。Microsoft Ref:預生成事件/生成後事件命令行對話框Microsoft Ref: 如何:指定生成事件 (C#)Ref:C# XCOPY命令 “預先生成事件命令行”和“後期... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...