網站遷移紀實:從Web Form 到 Asp.Net Core (Abp vNext 自定義開發)


問題和需求

從2004年上線,ZLDNN.COM運行已經超過16年了,一直使用DotNetNuke平台(現在叫DNN Platform),從最初的DotNetNuke 2.1到現在使用的7.4。先是在亦庄的獨立服務器托管,后來遷到美國的PowerDNN的雲服務器ECS,再后來遷移到阿里雲的ECS,采用Windows 2008系統,運行幾年以后,C盤已經滿了,可又沒有辦法清理,網站速度越來越慢,干脆長痛不如短痛,徹底更新一下。

DotNetNuke嚴重依賴Web Form技術,其開發團隊到現在也沒有找到從.Net Framework遷移到.Net Core以及最新的.Net 5或.Net 6的合適技術路線,導致其只能在Windows下運行。另外一個問題是DotNetNuke只能使用SqlServer數據庫,無法使用更便宜更靈活的數據庫。網站的遷移實際上是在滿足現有基本功能的前提下,采用新的技術重新開發。在選擇新的技術之前,首先需要梳理一下網站的功能,確定哪些需要保留,哪些可以通過其它方式替代,哪些可以暫時不實現。網站需要保留的部分包括:

  • 數據:包括用戶數據、訂單數據、技術支持數據等。
  • 網站頁面的Url: 大部分Url已經是SEO友好,但有些頁面仍然采用web form模式,比如GetLicense.aspx,這部分Url也需要保留。
  • 關鍵功能:諸如訂單接收、產品激活等。

其它的需求還有,希望網站可以運行在維護成本比較低的輕量級應用服務器中,可以采用MySql等開源數據庫,視覺效果上盡量與原有系統相同等等。還要留有用戶管理已經用戶注冊的接口。

在大的技術路線上,仍然采用.Net體系,研究了幾種技術,包括Qutane、Orchard等,最后決定采用Abp vNext進行開發。

開發

將開發中遇到的具體問題和最終的解決方案總結一下。

外觀

采用ABP自帶的Theme,根據現有網站的風格進行修改,保持風格大體一致。修改的辦法是從Abp源碼中復制Theme相關文件到自定義項目對應的目錄中,直接修改就可以了。需要修改的文件如下圖:

網站的顏色等需要修改文件global-styles.css:

首頁

DotNetNuke完全采用動態頁面,原來的首頁采用的是HTML模塊加上DNNArticle的子模塊,考慮到首頁的更新頻率不高,這次采用靜態頁面。

維護頁面

這部分主要是產品、版本、訂單等等的維護,屬於標准的CRUD界面。這部分采用ABP的標准化設計,首先設計各個實體,然后使用AbpHelper.Gui和AbpHelper.CLI生成相關代碼和界面。所生成的界面基本可以使用,需要改造的地方是增加查詢功能和調整權限。這里簡單介紹一下如何增加查詢功能。
ABP MVC/Razor Page 模板生成的基於DataTables.Net的頁面支持分頁和排序,但缺省情況下不支持查詢,需要根據實際情況自行添加。我們可以利用DataTables.Net自帶的查詢功能實現查詢。

首先修改Application項目,增加帶有查詢的Application服務。先在PagedAndSortedResultRequestDto基礎上定義帶有關鍵字的Dto:

    public class OrderNotificationSearchDto: PagedAndSortedResultRequestDto
    {
        public string Key { get; set; }
    }

然后在Application 服務中增加查詢服務:

        public async Task<PagedResultDto<OrderNotificationDto>> GetSearchListAsync(OrderNotificationSearchDto input)
        {
            var query = await CreateFilteredQueryAsync(input);
            if (!string.IsNullOrEmpty(input.Key))
            {
                query = query.Where(o => o.InvoiceID.Contains(input.Key)
                || o.OptionName.Contains(input.Key) 
                || o.PackageName.Contains(input.Key)
                || o.BillToEmail.Contains(input.Key));
            }

            var totalCount = await AsyncExecuter.CountAsync(query);

            query = ApplySorting(query, input);
            query = ApplyPaging(query, input);

            var entities = await AsyncExecuter.ToListAsync(query);
            var entityDtos = await MapToGetListOutputDtosAsync(entities);

            return new PagedResultDto<OrderNotificationDto>(
                totalCount,
                entityDtos
            );
        }

然后需要改造客戶端,首先將index.js中datatables的設置searching改為true:

   var dataTable = $('#OrderNotificationTable').DataTable(abp.libs.datatables.normalizeConfiguration({
        processing: true,
        serverSide: true,
        paging: true,
        searching: true,

接下來修改ajax的定義:

//ajax: abp.libs.datatables.createAjax(service.getList),
        ajax: abp.libs.datatables.createAjax(service.getSearchList, inputAction, responseCallback),

將getList修改為新的getSearchList,增加新的傳入參數和Callback。這兩個函數定義如下:

   var inputAction = function (requestData, dataTableSettings) {
        var ctl = $("#OrderNotificationTable_filter input").val();

        return {
            key: ctl,
        };
    };

    var responseCallback = function (result) {

        // your custom code.

        return {
            recordsTotal: result.totalCount,
            recordsFiltered: result.totalCount,
            data: result.items
        };
    };

網站數據的導入

這部分主要包括產品數據和與激活相關的數據,采用自己寫的一個面向.Net Core的ADO庫,將原有的數據導出到Xml中,在新的應用中從Xml中讀取數據進行初始化。

產品內容頁

產品的內容原來保持在數據庫中,現在改為在文件中保存,加載產品頁時,從文件讀出展示。

外部數據交換

主要包括接收從DNNStore發來的數據和產品激活兩部分。采用Application Service實現,通過Apb框架的動態Web Api可以訪問。

Url重定位

包括與外界交換數據的Url和為了保證SEO一致的界面Url。采用.Net Core的ReWrite中間件實現,感覺這部分真的很好用。代碼如下:


            var options = new RewriteOptions()
            .AddRewrite(@"^GetLicense.aspx", "Products/Services/ManualActivate",true)
            .AddRewrite(@"^Products/currentpage/(\d+)", "Products?currentpage=$1", true)
            .AddRewrite(@"^ProductDetail/(.+)", "Products/ViewDetail?name=$1", true)
            .AddRewrite(@"^LicenseCode.aspx", "api/app/activate/req-license-code", true)
            .AddRewrite(@"^desktopmodules/OrderNotification/OrderNotify.aspx", "api/app/activate/save-order", true)
             app.UseRewriter(options);

還有其它一些細節包括關閉多租戶、關閉用戶注冊、國際化修改等等。

從十一前開始,斷斷續續開發了兩到三周的時間。

部署和運行

以前一直在Windows生態中,部署應用似乎不是大問題,只有在IIS上創建網站或者應用就可以了。現在希望將ZLDNN.COM遷移到阿里雲的輕量級服務器,在Linux系統下部署,還是遇到一些挑戰。

首先解決.Net Core應用在Linux上運行的問題。由於在生產環境中只運行一個.Net Core應用,所以在生成部署文件時采用獨立運行模式,這樣就不需要在生產環境中安裝.Net框架。這一步沒有遇到大問題,測試應用能夠運行。

然后是ABP應用在生產環境上運行,這里遇到一個問題,Couldn’t find a valid ICU package installed on the system.這個問題在本地測試沒有遇到,查了一下是沒有安裝ICU庫,安裝完成后問題解決了。

數據庫的配置沒有遇到太大麻煩,但在后期運行時出現了MySql異常退出的問題,發現是內存問題,創建內存交換文件后解決了。

Apache服務器配置花了一些時間,因為兩個域名駐留在同一個服務器上,需要將Apache服務器配置為反向代理服務器,由於對Apache服務器不熟悉,折騰了一些時間,不過最后也成功了。

到現在新網站運行了兩個多月,基本沒有遇到太大的問題。效果還是不錯的,速度提升很多。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM