一些在開發網頁中會用到的小技巧,幫助改善開發的效率
列出目前幾個自己常用的:
※善用using
using完的物件會自動Close與Dispose,所以建議需要Dispose的物件都可以使用using
像是SqlConnection, SqlCommand, SqlDataReader...
using (SqlConnection conn = new SqlConnection("xxx"))
{
conn.Open();
} // 結束時不需要Close跟Dispose
※用@來設定多行的SQL語法
雖然我個人比較推薦把SQL語法都寫在查詢產生器中(減少程式碼複雜度,還能驗證)
不過某些時候還是必須要把SQL寫在code中
從Java轉過來的人可能會這樣寫
string sql = "SELECT field1, field2" +
"FROM table1" +
"WHERE field3 = @Param1";
其實在ASP.NET不需要這麼麻煩每一行要串接,在字串前加上@就能做到跨行:
string sql = @"SELECT field1, field2
FROM table1
WHERE field3 = @Param1";
※用TryParse轉換可能會出錯的字串
幾乎所有的基本型態都有TryParse方法
TryParse的特點是如果字串轉換失敗,不會拋出Exception
如果出錯後,變數會變成初始值0,如果希望同時給予不同值,可以這樣寫:
int i;
if (!int.TryParse("", out i))
{
i = 100;
}
※用??代替麻煩的條件判斷
string str;
if (WebConfigurationManager.AppSettings["xx"] != null)
{
str = WebConfigurationManager.AppSettings["xx"];
}
else
{
str = "defaultValue";
}
string str = WebConfigurationManager.AppSettings["xx"] ?? "defaultValue"; // 與上面同義
string str = val1 ?? val2 ?? val3 ?? val4; // 依序判斷val1, val2, val3, val4是否有值,有值即設定值
※GridView要如何做到按下一行自動選取該行(select row)
在GridView的RowDataBound輸入以下code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + e.Row.RowIndex);
e.Row.Style.Add(HtmlTextWriterStyle.Cursor, "pointer"); // 滑鼠移上去時,變成點選樣式
}
}
但輸入完後會出現以下訊息
解決方法:覆寫該頁Render,註冊其事件驗證
protected override void Render(HtmlTextWriter writer)
{
for (int i = 0; i < this.GridView1.Rows.Count; i++)
{
Page.ClientScript.RegisterForEventValidation(this.GridView1.UniqueID, "Select$" + i.ToString());
}
base.Render(writer);
}
※在刪除按鈕點下去前先跳出一個確認視窗,選擇確定才PostBack
Button的OnClientClick輸入
return confirm("Are you sure?");
※如何顯示MessageBox
ASP.NET沒這東西,你只能動態註冊JS呼叫alert
ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('" + Message + "');", true);
※要怎麼做到按下按鈕後跳出新視窗(open new window),在新視窗輸入內容(Ex.帳號密碼)後回傳(return value)的效果
純ASP.NET無法做到,只能使用JS,請搜尋關鍵字showModalDialog
以下方法不是最好的方法...如果有更好的作法請跟我說
假設要從A頁面呼叫B頁面,輸入完資料再回傳A頁面
在A.aspx寫入此JS (要直接寫或用動態註冊皆可)
var returnValue = window.showModalDialog(url, "", "dialogWidth:300px;dialogHeight:300px;"); // 還有很多參數可用
if (returnValue != undefined) {
__doPostBack(target, returnValue); // target自訂
}
在B.aspx寫入此JS
function selectBack(valueString) {
window.returnValue = valueString;
window.close();
}
在B.aspx的控制項上呼叫此方法
javascript:selectBack('" + encodeKeyString + "')
最後在A.aspx.cs接收此PostBack參數
※網頁原始檔部份有內建的排版(format)工具嗎?
網頁全選後按右鍵,選擇"格式化選取範圍"
※如何避免SQL衝突 (兩人修改同一筆資料)
假設有個資料表是這樣(id是Primary Key)
id name
1 小明
2 小華
如果資料庫要修改欄位內容,一般SQL會寫
Update name = @Name Where id = @id
但如果同時有兩個人要修改小明的name,就會變成"後進先寫入"
也就是後面寫入的資料會蓋過前面寫入的資料
解決法是把SQL改寫成這樣
Update name = @Name Where id = @id and name = @origin_name
這樣當第一個人把"小明"修改成"小明1"之後
第二個人就無法找到name=小明的資料,所以不會覆蓋到第一個人的修改結果
※DropDownList要怎麼根據Text或Value改變他的選取值
DropDownList1.SelectedIndex = DropDownList1.Items.IndexOf(DropDownList1.Items.FindByText("text"));
DropDownList1.SelectedValue = "XXX"; // 如果只要根據Value選擇,直接這樣寫就好
※DateTime要怎麼重新設定時間,且不使用new
沒有辦法,請直接用new給予新值
DateTime dt = new DateTime(2012, 12, 12);
dt = new DateTime(2011, 11, 11);
DateTime是struct,所以直接取代掉就好了
struct是value type,所以並不會浪費記憶體
※如何讓DateTime指定為該月最後一天?
1. DateTime.DaysInMonth(year, month);
2. new DateTime(year, month, 1).AddMonths(1).AddDays(-1);
※SQL要怎麼把很多筆資料(multi row)變成單行字串(single string)?
比方說今天有資料如下
ID Name
1 Name1
1 Name2
2 Name1
2 Name3
2 Name5
希望轉成以下的欄位
ID Name
1 Name1,Name2
2 Name1,Name3,Name5
如果是MSSQL有個偷吃步的方法,就是使用FOR XML PATH('')語法
將取得的欄位轉變成一個用空白tag包覆的XML內容
SELECT A.ID,
(
SELECT B.Name + ','
FROM [TableB] AS B
WHERE B.ID = A.ID
FOR XML PATH('')
) AS Name
FROM [TableA] As A
※GridView某欄位在設定Visible=false後,PostBack之後無法取得該欄位的值
因為這個欄位在一開始產生網頁的時候就不會寫進去,所以自然無法取得不存在的資料
解決法
HeaderStyle跟ItemStyle設定CSS,CSS內容為display:none;
※字串直接串接比較好還是用string.Format串接比較好?
用string.Format串接比較快,因為其內部是使用StringBuilder實作
※decimal跟double的差別?
Decimal 不是浮點數資料型別。Decimal 結構會保存二進位整數值,加上正負號位元和整數縮放比例,指定值的哪一部分是小數部分。
簡單的說,double因為是用byte去儲存小數,所以每次都會有誤差,而decimal是用十進位去存小數,所以不會有誤差
如果要儲存金額等這種不允許誤差的數值,就要用decimal
※那為什麼List可以直接放基本型別?
List<int> list = new List<int>(); // 像這樣
因為C#會自動幫你做轉換
※int.Parse跟Convert.ToInt32有什麼差別?
1. int.Parse只能傳入string,Convert.ToInt32可以讀取各種型態
2. 當傳入參數為null時,int.Parse會拋出exception,Convert.ToInt32會回傳0
資料參考來源:http://catchtest.pixnet.net/blog/post/28219055-asp.net-%E4%BD%BF%E7%94%A8%E7%AD%86%E8%A8%98