如題今天來做可以把留言的資料存到資料庫的留言板,參考範例嘉義縣公共汽車管理處的旅客留言板,那就開始吧。
製作留言板分成三篇,這邊附上其他篇連結:
留言板中篇點這
留言板下篇點這
首先要先觀察需要存到資料庫的資料有哪些?
從嘉義縣公共汽車管理處留言板可以發現,會存進資料庫的資料就只有留言的內容及回覆的內容,所以先創立留言板資料庫及兩個資料表,一個存放留言另一個則存放回覆內容。
資料庫名稱:message_board
留言板的資料表:message_board(下圖下)
回覆留言資料表:reply(下圖上)
並把兩個資料表主索引的線給拉好,可參考主索引鍵與外部索引鍵
建立ASP.NET新專案。
接下來先加入兩個Web表單,乘客留言板首頁(Message_Index)和新增留言(Message_Add)的頁面。
先到Message_Index的設計模式,工具箱拉一個Button並將Text改成'我要留言'和一個GridView及SqlDataSource(如下程式碼及圖)。
<form id="form1" runat="server">
<div>
</div>
<asp:Button ID="Button1" runat="server" Text="我要留言" />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"></asp:SqlDataSource></form>
接下來對SqlDataSource設定資料來源,新增連接字串,新增方法可參考我的上一篇或ASP.NET與資料庫的聯繫,選擇message_board資料表並全選全部欄位按確定。
最後確認Web.config有沒有出現連接字串。
因為首頁顯示的留言資訊有編號跟回應且沒有顯示id跟留言內容,所以再GridView與SqlDataSource資料繫結後需要新增及刪除幾個欄位。
選擇資料來源後,對GridView右上角的箭頭按編輯資料行,將不要的欄位打「X」。
並且加入兩個TemplateField,並將欄位名稱改名(選取欄位在HeaderText做更改),使用上下箭頭來排列欄位位置,按下確定就完成了。
接下來在編號欄位裡面使用行號索引:Container.DataItemIndex,讓編號可以依序遞增,索引從0開始所以必須要+1,如下:
<asp:TemplateField HeaderText="編號">
<ItemTemplate>
<%# Container.DataItemIndex + 1%>
</ItemTemplate>
</asp:TemplateField>
因為在留言板首頁,主題是有個超連結可以點擊的,所以必須將主題欄位放置一個HyperLink工具。
先對GridView1右上角箭頭點開選編輯資料行,將主題轉換為TemplateField(點擊主題按右邊藍色的「將這個欄位轉換為TemplateField」),轉換成TemplateField就可以讓我們放置控制物件。
接下來按確定後,再到編輯樣板的頁面(一樣GridView1右上角箭頭點開),在下拉式選單中找到剛剛已經設定好的主題欄位,並將原本預設的Label刪掉並切放一個HyperLink,可直接從工具拖曳過去。
接著對GridView1結束樣板編輯,因為主題點開的那一個Web還沒有創立,所以之後再做連結。
然後再來是是將GridView1的選擇資料來源從SqlDataSource1改成無,跳出來的視窗記得按否。接著再把SqlDataSource1改刪除吧XD
現在要做的是這頁的功能,也就是新增留言。
接下來對著我要留言的Button點擊兩下,最自動跳到Message_Index.aspx.cs
直接貼上跳轉的方法,讓點擊Button後會自動跳到Message_Add的頁面。
Response.Redirect("Message_Add.aspx");
Response是由Server回傳給Browser的物件,而Redirect()是一種跳轉到其他頁面的方法。可參考[ASP.NET] 網頁常用物件-初淺談Response物件和[ASP.NET] 網頁常用物件-網頁跳轉的比較及實際範例說明。
接下來到Message_Add.aspx建立TextBox,要有標題、暱稱、內容三個以及一個送出的Button及一個重新填寫的input(可從工具箱->HTML->Input(Reset)拖曳,這是預設的重新填寫),間單的用排一下版型。
然後將內容的TextBox右鍵屬性,textMode選MultLine就可以將TextBox向下拉XD,然後可以順便設定寬與高。
標題<asp:TextBox ID="Message_Header" runat="server" ></asp:TextBox>
<p>
暱稱<asp:TextBox ID="Message_Name" runat="server"></asp:TextBox>
</p>
內容 <asp:TextBox ID="Message_Main" runat="server" Height="477px" TextMode="MultiLine" Width="596px" ></asp:TextBox>
<br />
<br />
<br />
<p>
<asp:Button ID="Confirm" runat="server" Text="確定留言" />
<input id="Reset1" type="reset" value="重新填寫" /></p>
將基本的工具拉好後,接著快速點擊「確定留言」的Button到Message_Add.aspx.cs頁面。
並將留言的資料傳入資料庫的程式碼打上,程式碼如下:
//取得config連接字串資訊
string getconfig = System.Web.Configuration.WebConfigurationManager
.ConnectionStrings["message_boardConnectionString"].ConnectionString;
//建立與資料庫建立起連接的通道,以getconfig內的連接字串連接所對應的資料庫
SqlConnection Connection = new SqlConnection(getconfig);
//要對SQL Server下達的SQL指令並且參數化
SqlCommand command = new SqlCommand($"INSERT INTO message_board( header,name, main) VALUES(@header, @name, @main)", Connection);
//賦予參數資料型態與值
command.Parameters.Add("@header", SqlDbType.NVarChar);//值必須是NVarChar的資料型態
command.Parameters["@header"].Value = Message_Header.Text;//給予的值是從Message_Header的Text來的
command.Parameters.Add("@name", SqlDbType.NVarChar);
command.Parameters["@name"].Value = Message_Name.Text;//給予的值是從Message_Name的Text來的
command.Parameters.Add("@main", SqlDbType.NVarChar);
command.Parameters["@main"].Value = Message_Main.Text;//給予的值是從Message_Main的Text來的
Connection.Open();//開啟通道
command.ExecuteNonQuery();//執行command的SQL語法,回傳受影響的資料數目
Connection.Close();//關閉通道
Response.Redirect("Message_Index.aspx");//確認留言完後要跳轉回首頁Message_Index.aspx
1.System.Web.Configuration.WebConfigurationManager.ConnectionStrings["ConnectionString的name"].ConnectionString: 取得Web.config與資料庫連接的連接字串資訊。
2.SqlConnection: 建立與資料庫建立起連接的通道。
3.SqlCommand: 對SQL Server下達的SQL指令。
4.Parameters :防止SQL Injection,有要對資料庫執行SQL語法最好要用參數動作。
5.ExecuteNonQuery(): 執行commandSQL語法的方法,並會回傳有受影響的數量。
6.Redirect: 跳轉頁面。
7.INSERT INTO: SQL的新增資料語法,可參考SQL-INSERT 新增資料的方法
留言時當然不能有任何的TextBox是空白的,所以在HTML5的TextBox有很多屬性可以使用,可將TextBox設定成必須填寫,且還可設定彈沒填寫時會跳出來的提醒文字。請將以下程式碼貼在TextBox內:
<asp:TextBox ID="Message_Header" runat="server" required="" aria-required="true" oninput="setCustomValidity('');" oninvalid="setCustomValidity('記得填寫標題ㄛ')" ></asp:TextBox>
1.設定為必填的屬性是:required=""
和aria-required="true"
2.彈挑出內容的文字是可以客製化的,需使用:oninvalid="setCustomValidity('文字內容')"
3.清除彈跳文字的紀錄:oninput="setCustomValidity('');"
若沒使用這行,假如有跳出警告文字,將清除不掉會一直出現XD
可參考這篇
而按執行測試一下留言是否有存入資料庫,填入資料,按下確定留言後,恩~看起來存入資料庫成功了><
若有任何問題或建議,請務必要糾正指教,感謝><
注意一下XSS問題 (Cross Site Scripting),可以試一下在內容輸入 "alert('我是惡意程式');",然後存檔會發生什麼事。
防治方法:濾除危險或不必要的 HTML tag: https://github.com/mganss/HtmlSanitizer
感謝小朱老師的提醒,不過ValidateRequest在ASP.NET預設是true,所以好像會擋掉(如下圖)><
原來使用參數化還有這招可以攻擊,讓我學到使用HtmlEncode來預防,真的謝謝小朱老師指導!
ValidateRequest=true 時會擋掉沒錯,但通常不可能都不會有 HTML 輸入的必要,這時就得把 ValidateRequest 設為 false,然後就是要自己處理把危險 HTML tag 濾掉的工作...
原來如此,了解了><我會多預防這類型的文字的,真的很感謝朱老師,謝謝!