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. }

參考







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

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