2018年3月15日 星期四
ASP.Net 對於從 Url 傳入 BIG5 中文的處理方法
由於 Request["param_name"] 是已經「壞掉」的資料,所以得從 Request.RowUrl 下手。
經過一番搜尋,得到的結果是下面這一段程式,用指定的 Encoding 來解碼 Request.RowUrl,再用 HttpUtility.ParseQueryString 拆解成 NameValueCollection
var request = HttpUtility.ParseQueryString(
HttpUtility.UrlDecode(
Request.RawUrl,
Encoding.GetEncoding("big5")));
這樣 request["param_name"] 就得到正確編碼的內容了
特記於此,以備日後查看。
2017年2月11日 星期六
於 .Net 4.5 使用 Crystal Report 的注意事項
最近接了一個定時抓資料產生報表的案子,想說應該很容易,沒想到卻因為 Crystal Report 的問題卡關了一整天
症狀是這樣的:服務一啟動就發生 1067 錯誤
看事件檢視器中的錯誤訊息是 System.IO.FileNotFoundException,但是卻不知道是哪個檔案找不到
卡了好幾個小時之後,轉個方向,改成用 Console 程式來產生報表,結果一跑就看到問題發生的原因了,是找不到這個檔案 "C:\Program Files (x86)\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Common\SAP BusinessObjects Enterprise XI 4.0\win32_x86\dotnet1\crdb_adoplus.dll"
可是根本就沒有這個目錄,怎麼可能找得到檔案呢?
把這個路徑拿去 google,一搜馬上就有結果了,原來要在 App.config 的 startup 節加上 useLegacyV2RuntimeActivationPolicy="true" 這個屬性。
也就是把
<startup>
改成
<startup useLegacyV2RuntimeActivationPolicy="true">
改好之後,重新建置,執行,果然正常了。
為免遺忘,特記述於此。
2015年5月12日 星期二
用 ZXing 製作帶有中文的 QRCode
ZXing 是一個一維/二維條碼製作與識別的 library,計畫首頁在 https://github.com/zxing
本文要說的是如何製作帶有中文的 QRCode。不用囉唆了,直接看 code
using ZXing; Bitmap bm = |
這樣就得到了一個 QRCode 圖片

簡單吧!
2013年6月10日 星期一
ASP.Net 隱藏 RadioButtonList 裡的項目
ASP.Net 的 RadioButtonList 是一個蠻好用的控制項,用了他就不用拉好幾個 RadioButton 了。不過有一個困擾的地方就是他的 Item 並沒有 Visible 的屬性,使得有時想要隱藏某些項目時感覺有些困擾
其實,沒有 Visible 屬性也沒有關係,他有 Arrtibutes 屬性可以用,只要用
RadioButtonList1.Items[0].Attributes.Add("style", "display:none");
或是
RadioButtonList1.Items[0].Attributes["style"] = "display:none";
就可以隱藏第 0 個 item 了
提供給大家參考
2012年3月21日 星期三
ASP.Net 要透過加入 AD 的 ExchangeServer 發郵件的方法
1. 讓 ASP.Net 信任 ExchangeServer 的自訂憑證
在 Global.asax.cs 裡面的 Application_Start 事件加入以下這行:
ServicePointManager.ServerCertificateValidationCallback +=
new RemoteCertificateValidationCallback(ValidateServerCertificate);
以及在 Global.asax.cs 加入這個靜態方法
public static bool ValidateServerCertificate(Object sender,
X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
return true;
}
using 要加入
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
2. 發郵件時程式
SmtpClient sc = new SmtpClient();
sc.Credentials = CredentialCache.DefaultNetworkCredentials;
sc.EnableSsl = true;
sc.Send(mm); // mm 是 MailMessage
3. 在 web.config 中設定好
<system.net>
<mailSettings>
<smtp from="寄信人信箱" deliveryMethod="Network">
<network host="郵件主機"
port="埠號"
userName="登入帳號"
password="登入密碼"
defaultCredentials="true" />
</smtp>
</mailSettings>
</system.net>
4. 將 IIS 的應用程式集區設定為「整合式」
2011年10月9日 星期日
用 NPOI 在 Excel 工作表中畫斜線
程式碼如下:
using NPOI; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; …… // 於工作表上建立 HSSFPatriarch,注意!一張工作表只可以建立一個 HSSFPatriarch HSSFPatriarch p = sheet1.CreateDrawingPatriarch() as HSSFPatriarch;
// new HSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2) // 就是從 (col1, row1) 儲存格的 (dx1, dy1) 點 // 到 (col2, row2) 儲存格的 (dx2, dy2) 點建立一個繪圖物件的涵蓋範圍 HSSFClientAnchor a = new HSSFClientAnchor(0, 0, 0, 0, 0, 0, 1, 1); // 建立一個 HSSFSimpleShape 繪圖物件,範圍是 a,物件會充滿整個範圍 HSSFSimpleShape s = p.CreateSimpleShape(a); s.ShapeType = HSSFSimpleShape.OBJECT_TYPE_LINE; // 設定線條類型為線條 s.LineStyle = HSSFSimpleShape.LINESTYLE_SOLID; // 設定為實線 s.LineWidth = 1; // 限定線條寬度為 1
2010年11月7日 星期日
ASP.Net GridView 的自訂資料繫結
在論壇上,常常看到有網友提出這樣的問題:如果資料值是 Y/N,要顯示 是/否 在 GridView 上,要如何做?
這個問題有幾種解法
第一種:使用 GridView.RowDataBound 事件,搭配 TemplateField
這種方法是大部分的書上會介紹的方法
RowDataBound 事件,會傳入一個型別為 GridViewRowEventArgs 的參數 e
e.Row 指的是 GridView 剛剛做完資料繫結的列
e.Row.DataItem 指的是用來做這個列的資料繫結的資料來源,型別是 object
如果以 DataTable 或是 DataSet 做資料來源,e.Row.DataItem 實際上是一個 DataRowView
所以,如果以 DataTable 或是 DataSet 做資料來源,(e.Row.DataItem as DataRowView).Row["欄位名稱"] 可以取得欄位的資料值
接下來,就是「數格子」,要知道你的 TemplateField 是第幾欄,還要知道要做自訂資料繫結的控制項是 ItemTemplate 的第幾個控制項
(e.Row.Cells[欄索引].Controls[控制項索引] as 控制項型別).Text =
(e.Row.DataItem as DataRowView).Row["欄位名稱"].ToString()
或是要知道自訂資料繫結的控制項的 ID
(e.Row.Cells[欄索引].FindControl("控制項ID") as 控制項型別).Text =
(e.Row.DataItem as DataRowView).Row["欄位名稱"].ToString()
這種方法的缺點是
- 如果在這個TemplateField 之前,加入或是刪掉了其他欄,或是修改了 TemplateField 的 ItemTemplate,事件處理都得修改
- 如果不是以 DataTable 或是 DataSet 做資料來源,e.Row.DataItem 事實上是什麼型別?
不確定因素太多,既麻煩又複雜!強烈不建議使用這個方法
第二種:使用單純自訂資料繫結,搭配 TemplateField
這種方法直接在 TemplateField 的 ItemTemplate 中放置一個 Label,並設置 Text 屬性的資料繫結為 Text='<%# Eval("欄位名稱").ToString() == "Y" ? "是" : (Eval("欄位名稱").ToString() == "N" ? "否" : "") %>' Text='<%# Eval("欄位名稱", "{0}") == "Y" ? "是" : (Eval("欄位名稱", "{0}") == "N" ? "否" : "") %>'
簡單明瞭,只是判斷是寫在 .aspx 裡面,而且當資料值是 DbNull 的時候會發生錯誤,如果還要加上判斷是否為 DbNull 的語法就更複雜了
因此,此方法建議使用於簡單判斷以及資料欄位不允許 null 的狀況
PS: Eval("欄位名稱") 與 Eval("欄位名稱", "{0}") 的不同點在於前者回傳的是 Object,後者回傳的是 String
第三種:使用自訂資料繫結方法,搭配 TemplateField
跟第二種方法類似,只是將 Label 的 Text 屬性的資料繫結改為呼叫一個自訂方法 (必須為 public 或 protected 方法)
Text='<%# YesOrNo(Eval("欄位名稱")) %>'
並撰寫後端程式碼如下:
protected string YesOrNo(object o)
{
string s = o == DbNull.Value ? "" : Convert.ToString(o);
return s == "Y" ? "是" : (s == "N" ? "否" : "");
}
這樣的好處是
- 不用數格子
- 沒有複雜的資料繫結語法
- 無論從何種資料來源做資料繫結,都可以適用
- 可檢查資料是否為 DbNull
2010年9月8日 星期三
多螢幕環境下,指定螢幕顯示畫面 (C#)
private void ChangeScreen(Form aForm, int screenId) { // 先將 Form 設定為 Normal aForm.WindowState = FormWindowState.Normal; // 改 Location aForm.StartPosition = FormStartPosition.Manual; if (screenId < Screen.AllScreens.Length) { aForm.Location = Screen.AllScreens[screenId].WorkingArea.Location; } // 最後設定成 Maximized aForm.WindowState = FormWindowState.Maximized; }
2009年10月30日 星期五
取得物件的私有欄位、呼叫已經綁定在物件上的事件
如果私有欄位定義在 base class 中,則傳入 obj.GetType().BaseType
執行範例一:
Field Name | Type | Static |
---|---|---|
EventPageIndexChanged | System.Object | Yes |
EventPageIndexChanging | System.Object | Yes |
EventItemCommand | System.Object | Yes |
EventItemCreated | System.Object | Yes |
EventItemDeleted | System.Object | Yes |
EventItemDeleting | System.Object | Yes |
EventItemInserting | System.Object | Yes |
EventItemInserted | System.Object | Yes |
EventItemUpdating | System.Object | Yes |
EventItemUpdated | System.Object | Yes |
EventModeChanged | System.Object | Yes |
EventModeChanging | System.Object | Yes |
Field Name | Type | Static |
---|
??怎麼沒有東西??
那麼改用 ListFields(dropDownList1.GetType().BaseType) 試看看
Field Name | Type | Static |
---|---|---|
EventSelectedIndexChanged | System.Object | Yes |
EventTextChanged | System.Object | Yes |
拿到這些私有欄位的名稱有什麼用?各位發覺到了嗎,這些私有欄位都是以 Event 開頭的,也就是說這些是用來儲存 Delegate 的私有變數
接下來,就可以利用以下的程式,來呼叫「已經綁定在物件上的事件處理函式」
2008年7月4日 星期五
詐砲的自訂公式
例如:加班費計算
有些人想要 ROUND(時薪 * 加班費比例) * 時數
有些人想要 FLOOR(時薪 * 加班費比例) * 時數
有些人想要 ROUND(時薪 * 加班費比例 * 時數)
有些人想要 FLOOR(時薪 * 加班費比例 * 時數)
於是就有程式人員這樣寫啦
switch(計算方式) { case "1" : 加班費 = ROUND(時薪 * 加班費比例) * 時數; break; case "2" : 加班費 = FLOOR(時薪 * 加班費比例) * 時數; break; case "3" : 加班費 = ROUND(時薪 * 加班費比例 * 時數); break; case "4" : 加班費 = FLOOR(時薪 * 加班費比例 * 時數); break; }第五種狀況出現時怎麼辦?改程式?寫程式一定要這樣歹命嗎?
來!我有一個詐砲方法給大家參考
就是請資料庫伺服器幫你算!
以 SQL Server 為例子
SELECT ROUND(@時薪 * @加班費比例, 0) * @時數
只要把 @時薪、@加班費比例、@時數 三個參數丟進去,就有計算結果啦
所以呢,「ROUND(@時薪 * @加班費比例, 0) * @時數」這一串文字就可以變成「加班費計算公式」的設定
反正加班費再怎麼算,都脫離不了時薪、加班費比例、時數三個參數
我覺得這個方法相當不錯,提供您參考喔~~
2008年6月17日 星期二
C# 使用 ADOX 建立新 Table
所以,有必要撰寫這樣的工具程式,以便於後續方便使用
使用 ADO 以及 ADOX 之前,要加入兩個 COM 的參考
- C:\Program Files\Common Files\System\ado\msado15.dll (ADODB)
- C:\Program Files\Common Files\System\ado\msadox.dll (ADOX)
接下來,撰寫程式如下
/// <summary> /// 建立 MDB 資料庫以及資料表 /// </summary> public class MDBCreate { private ADOX.CatalogClass catalog = new ADOX.CatalogClass(); private ADODB.Connection connection = new ADODB.ConnectionClass(); private string createConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}"; private string _fileName = ""; /// <summary> /// MDB 檔案名稱 /// </summary> public string FileName { get { return _fileName; } set { _fileName = value; } } /// <summary> /// 建立新的 MDB 資料庫 /// </summary> /// <param name="deleteIfExist">是否刪除現有的</param> /// <returns>是否建立成功</returns> public bool CreateMDB(bool deleteIfExist) { try { if (deleteIfExist) { if (File.Exists(_fileName)) File.Delete(_fileName); } catalog.Create(String.Format(createConnStr, _fileName)); return true; } catch { return false; } } /// <summary> /// 利用 DataTable 結構,於 MDB 檔案中建立新的 Table /// </summary> /// <param name="tableName">Table 名稱</param> /// <param name="sourceTable">包含表格結構的 DataTable 執行個體</param> /// <returns>是否建立成功</returns> public bool CreateTable(string tableName, DataTable sourceTable) { string connStr = String.Format(createConnStr, _fileName) + ";Persist Security Info=False"; connection.Open(connStr, "", "", 0); catalog.ActiveConnection = connection; ADOX.TableClass table = new TableClass(); ADOX.DataTypeEnum fieldType = ADOX.DataTypeEnum.adWChar; int fieldLength = 0; table.Name = tableName; for (int i = 0; i < sourceTable.Columns.Count; i++) { DataColumn column = sourceTable.Columns[i]; switch (column.DataType.FullName) { case "System.Boolean": fieldType = ADOX.DataTypeEnum.adBoolean; break; case "System.Byte": fieldType = ADOX.DataTypeEnum.adUnsignedTinyInt; break; case "System.Char": fieldType = ADOX.DataTypeEnum.adWChar; fieldLength = column.MaxLength; if (fieldLength == -1) fieldLength = 255; break; case "System.DateTime": fieldType = ADOX.DataTypeEnum.adDate; break; case "System.Decimal": fieldType = ADOX.DataTypeEnum.adCurrency; break; case "System.Double": fieldType = ADOX.DataTypeEnum.adDouble; break; case "System.Int16": fieldType = ADOX.DataTypeEnum.adSmallInt; break; case "System.Int32": fieldType = ADOX.DataTypeEnum.adInteger; break; case "System.Int64": fieldType = ADOX.DataTypeEnum.adInteger; break; case "System.SByte": fieldType = ADOX.DataTypeEnum.adSmallInt; break; case "System.Single": fieldType = ADOX.DataTypeEnum.adSingle; break; case "System.String": // 因為 MDB 檔的文字欄位最大長度是 255 // 所以超過時,以 memo 欄位存放 if (column.MaxLength > 255) { fieldType = ADOX.DataTypeEnum.adLongVarWChar; fieldLength = 0; } else { fieldType = ADOX.DataTypeEnum.adVarWChar; fieldLength = column.MaxLength; if (fieldLength == -1) fieldLength = 255; } break; case "System.UInt16": fieldType = ADOX.DataTypeEnum.adSmallInt; break; case "System.UInt32": fieldType = ADOX.DataTypeEnum.adInteger; break; case "System.UInt64": fieldType = ADOX.DataTypeEnum.adInteger; break; case "System.Byte[]": fieldType = ADOX.DataTypeEnum.adLongVarBinary; break; } // 將新增的欄位物件加入 Table 中,並設定欄位屬性為可 null table.Columns.Append(column.ColumnName, fieldType, fieldLength); table.Columns[i].Attributes = ColumnAttributesEnum.adColNullable; } try { // 將新增的 Table 物件加入 Catalog 物件,以達到建立新 Table 的目的 catalog.Tables.Append(table); catalog.ActiveConnection = null; return true; } catch { return false; } finally { connection.Close(); } } }