顯示具有 C# 標籤的文章。 顯示所有文章
顯示具有 C# 標籤的文章。 顯示所有文章

2020年12月15日

.net 字串比較


故事先來一下:

DB存的是str1,使用者輸入的是str2,程式說這兩個字串不一樣,我一眼就看出 ... 看出這個問題我要找很久 …

其實也還好,馬上想到是字串比對StringComparison的問題

原本用的是OrdinalIgnoreCase,但這串奇怪語言,我猜應該是要包含點什麼文化特性,試的結果如下:

str1 = "HÀ HỮU TUYÊN";
str2 = "HÀ HỮU TUYÊN";

 

 

https://docs.microsoft.com/zh-tw/dotnet/standard/base-types/best-practices-strings

官方建議,大概總結一下
  1. 沒有文化特性(只有英文、符號)的比較可以用Ordinal,OrdinalIgnoreCase(效能也比較好)
  2. 有文化特性的(多語系)請用CurrentCulture
  3. 沒事不要用InvariantCulture
  4. 用string.Equals 最好指定 StringComparison,給明確的規則
  5. string.Compare,string.CompareTo不要拿來檢查是否相等(官方寫的沒給理由,有空或有心人再找)

2017年8月8日

Asp.net Web client使用excel元件發生錯誤

擷取元件 (CLSID {00024500-0000-0000-C000-000000000046}) COM Class Factory 失敗
擷取元件 (CLSID  {00024500-0000-0000-C000-000000000046})  COM Class Factory失敗,因為發生下列錯誤: 80040154 類別未登錄 (發生例外狀況於 HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
描述在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。 

例外狀況詳細資訊System.Runtime.InteropServices.COMException: 擷取元件 (CLSID  {00024500-0000-0000-C000-000000000046})  COM Class Factory 失敗,因為發生下列錯誤: 80040154 類別未登錄 (發生例外狀況於 HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
以下嘗試的解決方式:

1. Start->run->regedit 
Find 00024500-0000-0000-C000-000000000046 ->資料夾按右鍵內容,安全性加入NETWORK SERVICE給予權限,找遍所有00024500-0000-0000-C000-000000000046相關的機碼全部設了Network service 與 IIS_IUSRS完全控制的權限,結果失敗
2. Start -> run -> DCOMCNFG
來想照著以上說明去「元件服務」設定DCOM元件,竟然沒有Microsoft Excel Application。因為Excel32位元,64位元的作業系統看不到該元件,結果失敗
3.在web.config 加入
帳號密碼請先使用本機administrator帳號試比較沒問題
若是 Server 2008 x64 請建立下述資料夾
C:\Windows\SysWOW64\config\systemprofile\Desktop
若是 Server 2008 x86 請建立下述資料夾
C:\Windows\System32\config\systemprofile\Desktop
以上的設定。結果成功
4. Start -> run -> mmc comexp.msc /32
元件服務 -> 電腦 ->我的電腦 ->DCOM設定 ->Microsoft Excel Application ->安全性->啟動和啟用權限&存取權限->自訂權限加入Network serviceIIS_IUSRS完全控制權限, 識別身份用互動式使用者。結果成功

參考:http://tsaiyuchi.blogspot.tw/2011/02/excel-manipulate.html#more



存著用,現在用不到,這抄別人的 … 

型別轉換


public class C
{
    public T Data;
}

public class C : C
{
}

public C c1;
public C c2;

上面的c1無法轉換成c2,但我就是有這種需求…可能是我設計的不好 … 
我的Interface中訂了 C Query(string str);
在各個實作介面的物件中,回傳是各種C ,C等等…
因為要統一在外面接到就直接把C轉成Json字串,
所以需要C能正常轉型成C。

最後是在C裡面實做implicit(隱含轉換)


public class C
{
    public T Data;

    public static implicit operator C ( C cc )
    {
        var obj   = new C ();

        obj.Data  = cc.Data;

        return obj;
    }
}

這樣c2 = c1;的時候就不會出錯了!

隱含轉換的準則:
  1. 不會拋出例外
  2. 不會遺失資訊
所以其他程式設計人員可以不用注意這個東西直接拿來使用。

相對來說,如果希望其他程式設計人員在做轉型時可以注意到會有差異,希望他有認知到有做轉型的動作,
那實做的implicit關鍵字要改成explicit這樣在轉換的時候必須加上轉型關鍵字,寫成

c2 = (C)c1;

2017年7月28日

呼叫泛型方法時Type為變數值

之前做過一次,呼叫泛型方法,但型態在寫的時候還沒決定,
或是這個型態是個變數,還未知的,要做成下面這樣

public GenericMethod(object obj);

Type type = someobject.GetType();
GenericMethod(someobject);
想當然程式寫成這個樣子是不可行的。
所以才寫這個筆記…

2017年7月19日

時區轉換失敗


今天碰到一個問題,程式要轉換時間的時候找不到時區,第三方程式丟過來的時區資訊是MET( Middle European Time ),找了方法除了寫程式去處理例外、用第三方元件,最可靠的應該是下面這個方法了。
下圖就是找不到時區時會丟出的錯誤:

圖一









2017年7月5日

C#反組譯

先記著一些反組譯比較麻煩的東西

一、
反組譯出來的程式碼中,如果出現  CallSite ,這個應該是程式碼裡面用了dynamic,這次的例子中有出現這個
public static CallSiteobject
, OHLCDto, object>> <>p__0;但我還不知道這些型態是怎麼決定的 … 先記一下

二、
程式碼中出現<>這種東西,大概就是編譯的時候編出來的,很有可能是delegate、()=>或是Lambda表示式

三、Function 上有[AsyncStateMachine(typeof(OHLCPublisher.d__6))]這種東西,這應該是這個Function是用Async做出來的

2017年4月27日

MySql binary type data read & write (by Json.net)


MySQL資料型態為BINARY時,DATA TABLE讀到C#中是binary array ( byte[] )
現在用的framework是 ZayniFramework,
裡面轉物件的方式是用NewtonSoft.Json(JSon.net),

table →serialize→string
string→deserialize→object

裡面的bite array在序列化之後會轉成base64的字串,

程式中有一段,先讀出來,再更新寫回去的地方出錯,
資料型態為bianry(1),
sql parameter裡就直接將Base64的字串寫回去,錯誤訊息寫說大小超過欄位設定,

結果最後是mysql server版本的問題,
一開始安裝的是最新版5.7.18,
後來換成5.6.20版本就解決了,
這個以後換新版不知道怎麼辦…有空應該要試一下…

2017年1月10日

Timer 執行完前次工作後再倒數

這裡用的Timer是System.Threading.Timer;

目的是在倒數計時的程式中,不要前一次工作還沒完成,下一次工作就開始執行。

看到兩種作法

  1. 用Thread中的Monitor去鎖定物件來做控制
  2. 改變計時器時間(這個比較準)

2017年1月6日

Winform DataGrid Binding

    下面是程式中需要的Grid 欄位長相

     1. 新增Class並繼承INotifyPropertyChanged,實作其function

2017年1月4日

oracle重複連線(關閉又開),帳號密碼錯誤

Persist Security Info=True;

今天碰到連線關閉又打開時報錯:使用者密碼錯誤(之類的,我忘了錯誤代碼…)
原來是連線字串上面的這個屬性搞鬼,預設為false,連線一次就會把敏感資訊清掉,敏感資訊就是帳號阿密碼之類的,如果上面屬性寫成true就不會清掉。

也不一定要設這個屬性,只是每次連線就要抓取本來的連線字串,不能用OracleConnection.ConnectionString