2025年3月3日 星期一

[ASP.Net]GridView自訂分頁處理

 

ASP.Net的GirdView在每次分頁處理時都會在重新抓取所有資料在進行分頁,遇到大量資料或是設計不良的情況下,在切換時頁面會卡住,造成使用者體驗不佳。


可以透過GirdView內建的參數以及SQL OFFSET語法來替代原先的分頁處理,以下為步驟說明


1.aspx加上GridView的幾個參數

AllowCustomPaging:自訂分頁處理旗標

AllowPage                :是否允許分頁

<asp:GridView ... AllowCustomPaging="True" AllowPaging="True">
	<PagerSettings Mode="Numeric"/>
    ...
2.aspx.cs新增PageIndexChanging、btnQuery、GetData、GetDataCount方法
 
//分頁處理
 protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e){
    GridView1.PageIndex = e.NewPageIndex;
    GridView1.DataSource=GetData(e.NewPageIndex, e.PageSize);
    GridView1.DataBind();
 }

//查詢按鈕
 protected void btnQuery(object sender){
	GridView1.VirtualItemCount=GetDataCount();
  	GridView1.DataSource=GetData(0, 10);
  	GridView1.DataBind();
 }
 
 //透過SQL取得資料
 private DataTable GetData(int PageIndex,int PageSize){
 	...
 	return GetDataBySQL(new Source{filter,PageIndex=PageIndex,PageSize=PageSize});
 }
 //透過SQL取得資料總筆數
 private DataTable GetDataCount(){
 	...
 	return GetDataCountBySQL(filter);
 }
3.SQL語法調整,這邊使用的是SQL 2012的SQL OFFSET語法(與EFCORE的Skip+Take語法相同)
    #region 特殊處理
    public int GetDataCountBySQL(filter filter){
    	//...回傳總筆數
    }
    
    public DataTable GetDataBySQL(filter filter,int PageIndex,int PageSize){
    		...
     #region 分頁處理
          if (!string.IsNullOrEmpty(PageIndex) && !string.IsNullOrEmpty(PageSize))
          {
              int pageIndex = 0;
              int pageSize = 0;
              if (int.TryParse(PageIndex, out pageIndex) && int.TryParse(PageSize, out pageSize))
              {
                  sbSql.AppendLine($@"OFFSET {pageIndex * pageSize} ROWS FETCH NEXT {pageSize} ROWS ONLY");
              }
          }
 	#endregion
          	...
    }
    
透過以上步驟就完成自訂的分頁處理囉!

參考


2025年3月2日 星期日

[NetCore]ASP.NET Core 啟動異常 - HTTP Error 500.30 - ANCM In-Process Start Failure

 問題 

在開發專案時跳出異常訊息,錯誤訊息為  HTTP Error 500.30 - ANCM In-Process Start Failure 這篇就針對此案例作簡單紀錄與分享若是有不清楚或是錯誤的地方歡迎討論予糾正

解決方法 
廢話不多說,先看案發現場的錯誤畫面
執行異常的程式代碼,看起來很單純的代碼
  1. public static void Main(string[] args)
  2. {
  3. CreateWebHostBuilder(args).Build().Run();
  4. }
  5.  
  6. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  7. WebHost.CreateDefaultBuilder(args)
  8. .UseStartup<Startup>();
  9.  
在錯誤訊息中提到應用程式無法啟動可能是因為 Application 啟動失敗、或是啟動時發生異常造成,建議解決方案為開啟事件檢視器進行確認,因此照著建議的除錯步驟找出問題的發生點

事件檢視器
開啟事件檢視器發現啟動 Application 時有多筆異常原因,過濾後有幫助的訊息如下
可以看到事件檢視器錯誤訊息為  Application '/LM/W3SVC/2/ROOT' with physical root 'D:\Marcus\git\SerilogWebAppLab\SerilogWebAppLab\SerilogWebAppLab\' hit unexpected managed exception, exception code = '0xe0434352'. Please check the stderr logs for more information. ,其中提到 exception code 為 0xe0434352,在 How do I fix a .NET windows application crashing at startup with Exception code: 0xE0434352 文章中提到此錯誤代碼為 .NET 在執行中異常的代碼,因此錯誤訊息也建議透過 stderr 紀錄來查看更多訊息 (一直挖挖蒐集麵包屑的概念),接著下一步是確認 stderr 相關 Log 紀錄。

ASP.NET Core Module stdout log
在 ASP.NET Core 中 stdout log 預設是關閉的,可以透過 Web.config 設定  stdoutlogEnable  開啟,如下
  1. <aspNetCore processPath="dotnet"
  2. arguments=".\MyApp.dll"
  3. stdoutLogEnabled="true"
  4. stdoutLogFile=".\logs\stdout"
  5. hostingModel="InProcess">
stdoutLogEnabled 為啟用 stdout 紀錄,stdoutLogFile 是設定輸出 Log 路徑。如果是使用 Visual Studio IDE 使用 IIS Express 執行的話,則可以到專案檔底下的隱藏資料夾中的 applicationhost.config 搜尋 aspNetCore 區塊設定
  1. ProjectName\.vs\ProjectName\config\applicationhost.config
修改後儲存 Web.config 檔案,重新執行一次應用程式,可以看到專案底下 Log 資料夾有新增指定檔案
檔名前面為 stdout 開頭,後面為時間戳記及處理事件代碼
  1. stdout_20190513222912_28664.log
開啟 Log 檔案,內容顯示無法 Application 啟動時異常原因
透過 stdout Log 得知異常原因為 CreateDefaultBuilder 方法時預設會去讀取 appsettings.json 檔案,但由於 json 檔案格式錯誤造成 application 啟動時無法正常啟動,因而顯示 HTTP error 500.30 的狀況發生,修正後即可正常執行,宣告除蟲成功 ! 

備註 : Troubleshoot ASP.NET Core on IIS 內文有提到因為沒有限制記錄檔大小或是數量上限,啟用可能會造成應用程式或是伺服器失敗,請在確認完畢後關閉  stdoutlogEnable  為 false。

Improve 
調整代碼在啟動時加上 try catch 記錄錯誤訊息,讓之後遇到同樣事情可以更快發現 :)
  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. InitialSerilog();
  6.  
  7. try
  8. {
  9. CreateWebHostBuilder(args).Build().Run();
  10. }
  11. catch (Exception e)
  12. {
  13. Log.Error(e.Message);
  14. throw;
  15. }
  16. }
  17.  
  18. private static void InitialSerilog()
  19. {
  20. Log.Logger = new LoggerConfiguration()
  21. .MinimumLevel.Information()
  22. .WriteTo.Console()
  23. .WriteTo.File("logs/log_.txt", rollingInterval: RollingInterval.Day)
  24. .CreateLogger();
  25. }
  26.  
  27. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  28. WebHost.CreateDefaultBuilder(args)
  29. .UseStartup<Startup>();
  30. }

參考







2024年12月15日 星期日

【.Net Core】 EF Core + Web API 實作


 EF Core是Entity Framework在.Net Core使用的版本,功能幾乎相同,但具有輕巧、高擴充性以及高效能等優點,建議各位學習。


通常在.Net Core如果要用ORM的方式會有兩種選擇分別是EF Core以及Dapper。

從其他網路文章可以看到這兩種在最新版的效能其實都很接近了,只是定位有點不同,以下列出我目前覺得他們的定位導向(如有錯誤歡迎打臉指正我)

EF Core:適用於簡易查詢,有 Migrations、LINQ Support以及Lazy loading等等優點

Dapper:適用於簡易查詢以及複雜查詢(各種Join或Union),原因是複雜查詢用T-SQL難度較低於用LINQ的EF Core。

網路文章提供的功能比較圖


從以上兩點可以看到其實可以在一個專案同時使用兩種不同的方式去使用各自的優點。

例如Rico大大提到的使用EF Core 的Code First跟Migration,Dapper則拿來用複雜Query(or store procedures)

那就廢話不多說,開始來實作玩玩看

這次標的為 .Net 6 Web API + EF Core 7


首先先建立專案(範例都用預設,有其他需求再自行調整)


建立完透過Nuget安裝以下Package

2024年8月21日 星期三

[React]開發常見問題

 


此篇文章記錄一下一些初學者開發React時比較常見的一些問題。

(2024/08/22 更新)


2024年3月22日 星期五

[jest]Software Testing

 

此篇要教各位如何去撰寫前端的測試流程,測試在CI/CD流程內是不可或缺的一環

例如下方的pipeline圖




開始前先來了解一下主要會使用到的元件
  • jest-environment-jsdom一般也指測試的執行環境(environment),目的是模擬瀏覽器的行為、API,讓開發者能在 Node.js 的環境下模擬瀏覽器的操作
  • jest:是一個用來執行 JavaScript 測試的框架(JavaScript Test Framework),又稱 test runner,它讓開發者能夠執行測試、撰寫斷言,提供的 API 像是 expect、describe、test、toBe、toEqual 等等。其他這類的 JS testing frameworks 如 Vitest、mochajs、Jasmine 等等
  • @testing-library/jest-dom:原本 Jest 就有提供許多不同的 matchers(例如,toBe()、toEqual()等等),@testing-library/jest-dom則是擴充了更多可以在 Jest 中使用的 matchers,讓開發者可以使用toBeInTheDocument()` 等這類和 DOM 有關的 matchers。
  • @testing-library/react:基於 @testing-library/dom,它讓開發者可以把 React 元件 render 到 DOM 上,像是 render、screen、rerender、unmount 等等。不需要搭配 Jest 才能使用。其他這類的工具如 Enzyme。
  • @testing-library/user-event:模擬使用者的操作來測試使用者與 UI 的互動。相較於 @testing-library/dom 中的 fireEvent 更能模擬使用者的行為。
  • @babel/plugin-transform-modules-commonjs:ESM轉譯成CJS的套件,如果有使用到第三方套件則必須載入。

了解套件後就可以開始設定專案

先安裝套件,可透過以下語法安裝

2024年2月21日 星期三

[Gitlab]CI-流程建置

 

CI(Continuous Integration)是Devops的軟體開發流程,主要針對程式碼變更後的自動建置和測試之後,定期將變更合併置主要Repository,CI的關鍵目標是能更快發現和解決問題、改善軟體品質還有減少驗證和釋出軟體更新所需的時間。


此篇文章將教你如何建立Gitlab CI流程

環境說明:

  • Gitlab (self-managed)
  • Gitlab Runner
  • Docker (windows)


首先在Docker上安裝Gitlab-Runner,輸入以下指令安裝Docker

2024年2月16日 星期五

[React]環境部署


透過以下的簡易步驟,來部署React網站


以下依照不同的Server列出說明

項次

部署位置

地端/雲端

部署方式

說明

1

Windows Server(iis)

手動

本地VM,測試環境或者待管Server時會使用

2

Azure

手動

透過VS CodeFTP去部署

3

Azure

自動

透過CI/CD方式去部署

 

 

 

 

 


  • Window Server(iis)

1.先設定iis站台的URL Rewrite (SPA網站都可參考此設定)

//Web.config

更多資訊可參考保哥此篇文章說明

2.使用Terminal執行語法npm run build,以產生實體檔(檔案預設放在dist

3.手動搬移檔案至Server

  •  Azure (手動上傳)

    手動上傳還可區分成VS Code部署以及FTP部署兩種

    • VS Code部署

  1. 安裝Azure App Service Extension
  2. 使用語法npm run build產生實體檔(檔案預設放在dist資料夾)
  3. 使用滑鼠右鍵對選dist資料夾中的Deploy to Web App…
  4.  點選Sign in Azure
  5. 選擇登入Azure帳號
  6. 登入成功後選擇建立Azure App Service段落所建立App Service
  7. 點選Deploy以部署到 App Service
  8. 佈署成功可點選右下角的Browse WebSite查看(須過一段時間才能正常顯示)

    • FTP部署

  1. 使用語法npm run build產生實體檔(檔案預設放在dist資料夾)
  2. AzureApp Service頁面點選左側的Deployment center
  3.  點選FTP credentials就可以看到FTP的連線設定
  4. 使用FTP工具(.Filezilla)連線並將欲部署的檔案更新上去。

  •  Azure (CI/CD)
因CI/CD會被SourceControl的不同影響,待有實作時再回補說明


 













[ASP.Net]GridView自訂分頁處理

  ASP.Net的GirdView在每次分頁處理時都會在重新抓取所有資料在進行分頁,遇到大量資料或是設計不良的情況下,在切換時頁面會卡住,造成使用者體驗不佳。 可以透過GirdView內建的參數以及SQL OFFSET語法來替代原先的分頁處理,以下為步驟說明 1.asp...