發表文章

目前顯示的是 9月, 2022的文章

[JavaScript]更版時客戶端瀏覽器有JS暫存檔導致錯誤

圖片
 問題: 在專案開發的時候,時常有可能會對某幾隻「js檔案」作修改,然而因為客戶端瀏覽器已有此支「js檔案」存在了,所以就算更版後也未能重新載入更新後的「js檔案」,需請使用者自行清除「瀏覽器暫存」或者案「ctrl+F5」重新載入資源。 然而讓使用者自行去作重新載入資源,感覺有些奇怪,我們應該要達到每次更版後,client端都可以重新載入資源才是正確的。 解決方法: 其實解決方法很簡單,就是在引用js參考的地方,加上版本號,即可讓瀏覽器判斷是否要重新載入新的「js檔案」。 *原本的寫法 < script src = "js\index.js" type = "text/javascript" > </ script > *修改後的寫法(?ver=修改日期) < script src = "js\index.js?ver=20220929" type = "text/javascript" > </ script >

[C#]API 傳 IPagedList物件 無法成功轉為JsonString

圖片
 問題: 之前在實作一個前後端分離的專案,實作的內容大概是這樣,前台傳給API端一個查詢條件,而API端須回傳一個「IPagedList」類別的列表資訊。不過卻在實作時發生問題,IPagedList一直無法成功序列化為Json String。 解決方法: (一)序列化 IPagedList 其實像「IPagedList」這種介面,或者是EF物件,據我的經驗好像都沒辦法利用「JsonConvert」套件序列化成功。如果是EF物件的話可能就要先轉換為DTO或者是ViewModel之類的模型才能成功轉換。 所以同理,我認為我們也一樣要先將「IPagedList」轉換為一個比較單純的類別模型,等成功轉換為「Json String」傳回前台端後,我們再將其轉換回「IPagedList」,那仔細去看「IPagedList」的結構,大致分為兩個屬性如下(圖一),Items會放列表資訊的List,而MetaData則是存資料大小,分頁大小,當前頁碼等資訊。 (圖一) 所以API端要序列化回傳的Model架構大致上就如下(圖二) (圖二) 那麼關於Items的取得,我們就直接將當前的「IPagedList物件」ToList即可取得;而MetaData,仔細看PagedListMetadata的內容,可以發現將「IPagedList物件」放入PagedListMetadata的建構子裡頭即可取得整個PagedListMetadata 物件 ,如下(圖三)。 (圖三) 好的,現在我們可以將「IPagedList物件」給序列化了,由於「PagedListMetadata」無法直接序列化,因此我們必須自訂一個,「PaginationMetaData」來替代「PagedListMetadata」。 *類別 public class PaginationMetaData { public int FirstItemOnPage { get; set; } public bool HasNextPage { get; set; } public bool HasPreviousPage { get; set; } public bool IsFirstPage { get; set; } public

[JQeury]Select2() 無法在搜尋字段中輸入文字

圖片
 情境: 我有一個select 的物件(Id假設為"Test"),在一個Modal Dialog上,不過不管我怎麼點擊紅線上的區域都沒反應,無法做關鍵字搜尋。 解決方法: 爬了一下文,發現應該是因為select是在裡Modal Dialog導致的關係,此時模組可能還focus在Modal Dialog的外層,導致不管怎麼點擊都選不到「搜尋關鍵字」的對話窗,這時候我們只要指定 Select2模組的 dropdownParent到這個 Modal Dialog即可。 方法(一)指定到select的Modal Dialog(假設Id為" modelDialog "): $('#Test').select2({ dropdownParent : $( "#modelDialog" ) }); 方法(二)指定到select的父層: $('#Test').select2({   dropdownParent : $( "# Test " ) . parent () }); 參考: Can't type in Select2 dropdown input search field (http://kevin-brown.com/select2/)

[windows] 更改目錄下檔案富檔名

圖片
 情境: 現在有一個目錄[Test]底下有兩個檔案「1.txt」、「2.txt」。 目前有一個需求,需要將「1.txt」、「2.txt」改為「1.doc」、「2.doc」。 實作: 使用「cmd  ren 指令」 語法: 1.開啟command=>cd到[Test]目錄 2.下指令 「ren *.txt *.doc」

[windows]如何刪除 加密過的zip 第一次輸入的密碼 紀錄

圖片
 問題: 我發現加密過後的壓縮檔只有第一次解壓縮的時候會要求密碼,從第二次解壓縮開始便不會要求密碼,而直接解壓縮,雖然是方便了點,可是感覺可能會有些資安上的問題。 解方方法: 這個問題應該就是windows會記錄密碼資訊的關係,他會依路徑將密碼紀錄到cmdkey裡面,雖然如果換了路徑或者重機開機都可以達成再度要求密碼的需求,不過我就是想直接把密碼remove掉,大致上有以下兩種做法: 情境: 我現在有一個加密後的壓縮檔「Test.zip」,並有第一次解密過了。 (一)直接輸入cmdkey list 找尋要刪除的資料將其移除 1.打開command=>輸入「cmdkey /list」找到想移除的key 2.輸入「cmdkey /delete {key}」 ex:「cmdkey /delete Microsoft_Windows_Shell_ZipFolder:filename=D:\桌面\Test.zip」 (二)建立一個bat檔,將所有跟.zip有關的cmdkey都移除 1.新增一個筆記本,輸入這行文字後存檔。 「 FOR /f "tokens=2-3 delims==" %%G IN ('cmdkey /list ^| find ".zip"') DO cmdkey /delete:"%%G=%%H"」 2.將這個筆記本的副檔名改為bat 3.雙擊這個檔案即可刪除成功

[C#]費氏數列(Fibonacci sequence) 程式邏輯

圖片
 定義: 實作: 參數:輸入10 1.依輸入的項目數量顯示數列 Console.WriteLine("請輸入要顯示的費氏數列項目數量"); var input = Console.ReadLine(); //將字串轉為int var num = int.TryParse(input, out int output) ? output : 0; var a = 0; var b = 1; Console.WriteLine($"第1項:{b}"); for (var i = 2; i <= num; i++) { var temp = a + b; Console.WriteLine($"第{i}項:{temp}"); a = b; b = temp; } 2.依輸入的項次取得該項次值 static void Main(string[] args) { Console.WriteLine("請輸入要顯示的費氏數列項目數量"); var input = Console.ReadLine(); //將字串轉為int var num = int.TryParse(input, out int output) ? output : 0; Console.WriteLine($"遞迴寫法 取得的值:{F(num)}"); Console.WriteLine($"動態規劃寫法 取得的值:{F(num)}"); Console.ReadLine(); } *遞迴寫法 /// <s

[JQuery] $ is not defined 問題

圖片
 問題: F12檢視原始碼的時候,發現「$ is not defined」問題。 解決方法: 其實這個問題很簡單,就是字面上的意思,有參考上的錯誤,最有可能的原因就是沒有引用到「 jquery.min.js」的參考導致的,只要在使用到Jquery的script前加上雲端 「 <script src= "http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type= "text/javascript" ></script>」 參考即可,或者可以將這些script內容複製下來建立一個js檔再引用也可以。

[小工具]Blog轉換字元工具

轉換字元「<」=>「&lt;」 轉換 清除

[C#]Cache Set And Get

圖片
實作: *CacheHelper /// <summary> /// 快取-Helper /// </summary> public static class CacheHelper { private static ObjectCache _cache = MemoryCache.Default; /// <summary> /// 設定 快取 /// </summary> /// <param name="key">快取Key</param> /// <param name="data">物件</param> /// <param name="cacheTime">快取保存時間(TimeSpan)</param> public static void Set(string key, object data, TimeSpan cacheTime) { CacheItemPolicy policy = new CacheItemPolicy(); policy.AbsoluteExpiration = DateTime.Now + cacheTime; _cache.Set(key, data, policy); } /// <summary> /// 取得 快取 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key">快取Key</param> /// <param name="result">

[Mvc] Alert 提示訊息 服務功能 概念與實作

圖片
 需求: 之前曾開發過一個專案,每次對資料庫做完動作之後,都會用RedirectToAction()的方式,重新載入頁面,我是覺得這個設計方式很有問題啦...畢竟如果執行有問題,那錯誤訊息的顯示只能用Tempdata來處理,而且使用者輸入的頁面資料都會不見。 不過沒辦法,這個專案已經是歷史共業了,只能硬著頭皮做優化了。 這個專案的設計方式是這樣的,如果遇到有錯誤訊息的情況,就會用TempData儲存錯誤訊息,然後在每個view再寫一個javascript去判斷TempData有沒有值,若有值就顯示alert這樣。 這樣的設計方式非常不好,一來重複性的code太多了,二來沒有一個統一的寫法會導致後期維護不易,因此我才想寫一個Alert Service來便於管理。 概念與實作: 大致上的想法就是建立一個「AlertHelper」,將寫入Tempdata的這個動作做集中管理,並且在layout寫一個javascript去判斷TempData有沒有值,這樣就不用每個頁面都有重複性的code,可以統一做管理。 1.建立一個「AlertModel」 public class AlertModel { public AlertType AlertType { get; set; } public string Message { get; set; } public AlertModel(AlertType alertType, string message) { AlertType = alertType; Message = message; } } 2.建立一個列舉 「AlertType」 public enum AlertType { None, Suceess, Information, Warning, Danger } 3.建立「AlertHelper」 public static class AlertHelper { private static readonly strin

[C#]在憑證存放區中找不到資訊清單簽署憑證

圖片
問題: 今天加入專案在建置的時候遇到「 在憑證存放區中找不到資訊清單簽署憑證 」的問題。 解決方法: 大概就只能去跟相關人員要憑證的檔案了,不過因為我這邊只需要建置成功,做個git版控而已,所以就便宜行事,勾選取消「簽署ClickOnce資訊清單(M)」選項就好。 1.專案右鍵點擊「屬性」 2.到「簽署」頁籤=>勾選取消「簽署ClickOnce資訊清單(M)」選項即可

[C#] 'System.OutOfMemoryException' 的例外狀況

圖片
 問題描述: 當我使用「Encoding.UTF8.GetString(bytes)」方法,想將FTP接回來的byte[]轉回txt文字內容時,發生了「'System.OutOfMemoryException' 的例外狀況」(如下圖)。 ps:遠端的這個txt檔確很大,有好幾MB。 解決方法: 這個問題的發生原因似乎是因為 字符串在 .NET 中始終是 unicode,因此 ASCII 字節數組將轉換為需要 676 MB 內存的字符串(建議使用 GetString()方法時不要超過10MB )。 我的解決方法是先new 一個 MemoryStream,用StreamReader將byte array裝進去後,再ReadLine(),一行一行讀,改成用 List 去裝 每行的資料。 code: var path = @"D:\桌面\1.txt"; var bytesFromFile = System.IO.File.ReadAllBytes(path); //原始方法 var str = Encoding.UTF8.GetString(bytesFromFile); //改成用 List 去裝 每行的資料 var list= new List<string>(); using (Stream stream = new MemoryStream(bytesFromFile)) { using (StreamReader sr = new StreamReader(stream)) { var line = string.Empty; while ((line = sr.ReadLine()) != null) { var value = line.Replace("\r\n", string.Empt

[C#]XML依名稱 取得 節點「 InnerText」 與「屬性值」

圖片
 實作: 需求: 取得下圖「節點b」的InnerText,「節點c」的InnerText與屬性(parameter)的value。 1.建立一個 XMLHelper public static class XMLHelper { /// <summary> /// 載入XML檔案 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public static XmlDocument Load(string fileName) { XmlDocument doc = new XmlDocument(); if(!string.IsNullOrWhiteSpace(fileName)) { doc.Load(fileName); } return doc; } /// <summary> /// 依名稱取得節點 /// </summary> /// <param name="node"></param> /// <param name="tagName"></param> /// <returns></returns> public static XmlNode GetElementsByTagName(XmlNode node,string tagName) { if(node==null||string.IsNullOrWhiteSpace(tagName)) {

[C#]建立XML文件

圖片
 實作: 需求: 要組成一個如下圖,包含有「version」,「encoding」,「DOCTPYE」等資訊的XML文件。 1.建立一個 XML Build 來組成 XML文件 public class XMLBuild { private XmlDocument _xmlDoc { get; set; } public XMLBuild() { _xmlDoc = new XmlDocument(); } /// <summary> /// 將XML 文件 儲存至 指定路徑 /// </summary> /// <param name="path"></param> public void Save(string path) { if(string.IsNullOrWhiteSpace(path)) { return; } _xmlDoc.Save(path); } /// <summary> /// 將XML 文件 儲存至 指定串流 /// </summary> /// <param name="stream"></param> /// <returns></returns> public MemoryStream Save(MemoryStream stream) { _xmlDoc.Save(stream); return stream; } /// <summary> /// 建立具有指定值的 XmlDeclaration 節點

[Git]遠端退版master

圖片
 實作: (1)說明: 要將master退版至commit版本[0189d03] 1.在目錄下,【開啟Git】=>下指令「 git checkout master 」確認目前是否在「 master」分支上 2.將本機的master版本退至 commit版本[0189d03]: *輸入指令「git reset --hard  0189d0343d1417bb671b113ddaa8c8d56ae7ab90」 3.強制推至遠端master上: *輸入指令「 git push origin master --force」 ps:這裡有個小坑,可能會遇到[remote rejected]的問題,這是遠端mater這個分支受到保護導致的,可以先去遠端介面移除保護,待push後再將保護加回來。 參考: git回退遠端

[Git]Git am *.patch

圖片
 實作: (1)說明: 目前我有一個 「repo A」(目前的遠端版本)跟一個「repo B」(源自於「repo A」,後續有再做commit,但一直沒有push到遠端上)。 (2)需求: 要將「repo B」的所有commit同步至「repo A」,並且push到遠端上 1.生成所需的patch檔( 參考 ) 這邊我採用「git format-patch [commit-id]」(生成某次commit(不含此次)之後的所有commit)來取得patch檔。 *在「repo B」路徑點擊右鍵(選取 Git Bash Here)=>輸入指令「git format-patch [commit-id],在此目錄下生成patch檔。 2.將這些patch檔移至某個資料夾內(範例這邊我是移至「patch-directory」) 3.在 「repo A」 shift+右鍵 開啟 「  Git Bash Here」=>輸入「Git am *.patch」指令 ps:這邊有幾個坑 (1)請記得一定要用 shift+右鍵 開啟 「 Git Bash Here」,不然會有權限問題,無法訪問目錄。 (2)請確定是否有包含目前「repo A」 節點後所有commit的patch檔案 ,不然會顯示找不到檔案的錯誤訊息。 (3)只要有錯誤發生最好都先下 「git am --abort 」復原變更。

[windows]將壓縮檔藏在圖片裡

圖片
 實作: 1.說明: 將「1.jpg」與「2.zip」(裡面包含一個2.txt)合併成一個檔案「3.jpg」 2.打開「cmd」=>輸入「cd 檔案的路徑」=>「copy /b 1.jpg+2.zip 3.jpg」 ps:或者可以直接在檔案所在路徑先「新增一個資料夾」=>輸入「copy /b 1.jpg+2.zip 3.jpg」後存檔=>將副檔名改為「.bat」=>執行。 3.取得藏在「3.jpg」裡的壓縮檔: 其實只要直接將「3.jpg」的副檔名改為「.rar」,再解壓縮就可以了。

[Git]SSL certificate problem: certificate has expired Completed with errors, see above. (使用本地憑證 解決此問題)

圖片
  錯誤訊息: git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks fetch --no-tags origin fatal: unable to access 'https://.git/': SSL certificate problem: certificate has expired Completed with errors, see above. 之前遇到這個問題的時候,有寫過一篇是用「 關閉SSL驗證 」的方式解決的,不過我覺得這個方法不太好,第一關閉ssl驗證有被入侵的風險,第二就算自己時常去關閉又打開也很麻煩,所以今天介紹的方法是更好一點的解決方法。 解決方法: 1.點擊瀏覽器左上角的鎖頭=>「已建立安全連線」=>「憑證有效」 2.點擊「詳細資料」=>「複製到檔案」=>選擇「Base-64編碼X.509」,將憑證載下來 3.在path:[ C:\Users\user ]底下找到檔案「 .gitconfig」並開啟 4.在 「 .gitconfig」裡加上一行 [http]   sslCAinfo = C:\\Users\\scott\\curl-ca-bundle.cer ,紅線的部分改為你剛剛下載的憑證路徑位置就可以了