在上一篇(中篇)的最後已經拉出了回應文章的頁面,今天就繼續接下去作業並且完成留言板,當作鐵人賽的一個Ending。
參考留言板範例:嘉義縣公共汽車管理處留言板
現在到Message_Reply.aspx連點確定回應Button兩下,會跳到aspx.cs頁面。
現在要讓回應的資料存進reply的資料表內,程式如下:
//下面if和else if 是當有其中一欄沒有填寫時會跳出的文字提醒,都有填寫才會存進資料庫
if (string.IsNullOrEmpty(Reply_Main.Text) && string.IsNullOrEmpty(Reply_Name.Text))
{
Message.Text = "請填名字跟內容";
}
else if (string.IsNullOrEmpty(Reply_Name.Text))
{
Message.Text = "請填名字";
}
else if (string.IsNullOrEmpty(Reply_Main.Text))
{
Message.Text = "請填內容";
}
else
{
string config = System.Web.Configuration.WebConfigurationManager
.ConnectionStrings["message_boardConnectionString"].ConnectionString; //取得config的.ConnectionStrings資料
SqlConnection Connection = new SqlConnection(config); //與資料庫做連接的通道
SqlCommand command = new SqlCommand($"INSERT INTO reply(name,main,messageID) VALUES(@name, @main,@id)", Connection);//下達要執行的SQL指令,將加入存進資料表內
//因為標題本來預設就會顯示文字所以不用新增進回應資料表內
//參數化的資料型態與值
command.Parameters.Add("@name", SqlDbType.NVarChar);
command.Parameters["@name"].Value = Reply_Name.Text;
command.Parameters.Add("@main", SqlDbType.NVarChar);
command.Parameters["@main"].Value = Reply_Main.Text;
command.Parameters.Add("@id", SqlDbType.Int);
command.Parameters["@id"].Value = Convert.ToInt32(Request.QueryString["id"]);//將取得的值轉成int
Connection.Open(); //開啟通道
command.ExecuteNonQuery(); //執行SQL並回傳影響的項目
Connection.Close(); //關閉通道
Response.Redirect("Message_Main.aspx?id=" + Request.QueryString["id"]);//跳轉至回應的留言內容區(用id來抓取)
}
1.QueryString["id"] : Request的一種屬性,可以取得網址上「 main.aspx?id= 」 等於後面的文字,也就是留言的id,在上一篇新增HyperLink時有寫入的連結。
在Page_Load的程式碼如下:
使用DataRedader將取得的資料顯示出來
if (!IsPostBack)//假如第一次載入
{
string id = Request.QueryString["id"];//取得網址上的內容並存成字串
string config = System.Web.Configuration.WebConfigurationManager
.ConnectionStrings["message_boardConnectionString"].ConnectionString;
SqlConnection connection = new SqlConnection(config);
SqlCommand Command =new SqlCommand($"SELECT id, header, name, main, initDate FROM message_board where(id =@id)", connection);
Command.Parameters.Add("@id", SqlDbType.Int);
Command.Parameters["@id"].Value = Convert.ToInt32(Request.QueryString["id"]);//讓網址的id變成參數的值
connection.Open();
SqlDataReader reader = Command.ExecuteReader();//使用DataReader
if (reader.Read())//每讀入一行(這邊只會讀進一行因為SQL下的條件只會取得一筆資料)
{
TextBox1.Text ="RE:"+ reader["header"].ToString();
//將取得留言資料的標題放在標題的Text,前面加上字串"RE"
}
connection.Close();
}
執行看看,恩~留言板id=10的標題有加上'RE'出現在回應標題了。
接著打上資料看有無存進資料庫,確認後確實有存進資料庫了><
現在要在Message_Main.aspx下方顯示出所有回應這篇留言的回應,因為會一直往下延伸,需要使用Repeater控制項,所以先從工具箱拉出一個Repeater,還有兩個用來接回應留言資料的Label然後命名id,並且使用<ItemTemplate>
包住。
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Label ID="who" runat="server"></asp:Label>
<asp:Label ID ="repmain" runat="server" ></asp:Label>
</ItemTemplate>
</asp:Repeater>
Repeater是ASP.NET的控制項,它會重複抓取資料,簡單來說在Repeater裡面的控制項,會抓取資料並重複顯示。
接下來在Message_Main.aspx.cs 的Page_Load內,寫入要讓Repeater取得資料並顯示出來的程式碼:
SqlConnection rconnection = new SqlConnection(config);
SqlCommand Rcommand =new SqlCommand($"SELECT id, messageID, name, main, initDate FROM reply where(messageID =@id)", rconnection);
Rcommand.Parameters.Add("@id", SqlDbType.NVarChar); //設定參數資料型態
Rcommand.Parameters["@id"].Value =Request.QueryString["id"]; //接id的值變成參數的值
rconnection.Open();
SqlDataReader rereader = Rcommand.ExecuteReader();
Repeater1.DataSource = rereader;//repeater的資料來源是從rereader來
Repeater1.DataBind();//執行繫結
1.ItemTemplate: 定義清單內項目的內容和配置。在Repeater樣板是必要的。
2.Repeater.DataSource: 取得或設定提供資料以填入清單的資料來源。
3.Repeater.DataBind(): 用來將 DataSource 屬性所指定的資料來源繫結至 Repeater 控制項。
這樣Repeater算是與資料庫做繫結成功了,不過要取得顯示什麼資料內容,還是需要在Label內下繫結語法:Text='<%# Bind("name") %>'
和 Text='<%# Bind("main") %>'
成功顯示回覆留言在下方了,且就算是多筆也都會出現,這就是Repeater控制項神奇的地方。
在回應欄位的ItemTemplate從工具箱拉一個Label。
接下來,要從資料庫找到回應幾筆的數量,要下SQL語法:"SELECT [id], [header], [name],[initDate] ,(select count(*) from [reply] where messageID=[message_board].id)as 回應 FROM [message_board]"
所以將command下的SQL語法改成上面SQL語法。
然後對回應的Label,下資料繫結Text='<%# Eval("回應") %>'
,抓取到回應的資料。
這樣回應欄位就能取得該留言回應的數量了,如下圖。
這樣大致上的留言板功能都完成了,可以留言、回應留言以及顯示留言內容,如果我之後還有想到要新增什麼功能會再更新的。
在新增留言頁面加上一個標籤用來接IP位置的資料。
取得IP位置副程式如下:
private string getIP()
{
//取得本機名稱
string hostname = Dns.GetHostName();
//取得本機的IpHostEntry類別實體
IPHostEntry ipHostEntry = Dns.GetHostEntry(hostname);
//取得
string ipAddress = "";
foreach (IPAddress ipaddress in ipHostEntry.AddressList)
{
// 只取得IP V4的Address
if (ipaddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
ipAddress = ipaddress.ToString();
}
}
return ipAddress;
}
還記得以前大學唸書時,準備期中期末考,就有在看iT邦的文章尋找答案、解除疑惑,但真的從來都沒有想過未來的某一天我竟然也在iT邦幫忙寫文章參加鐵人賽,雖然寫的只是入門系列的文章,但還是很感動,希望可以幫助到其他有需要的人。
真的很感謝火箭隊團隊,洧杰老師及賈斯丁老師的教導及同學們彼此互相學習、努力及加油打氣,還有各位iT邦大神們的不吝指教,尤其是小朱大大給了我很多建議,真的很用心,受益良多,雖然30天完賽了,但我還是會繼續努力學習的。