Views: 4
本來想在一篇把SSMS跟SQL那邊簡單交代清楚,沒想到寫了三篇,這篇重點在Webform存入資料庫與一點點表單驗證。講怎麼將資料庫存入資料表。
表單填寫資料存入資料表大致流程
- 使用者的電腦:使用者填單+送出
- 網頁伺服器:收資料+檢查資料+寫入資料庫
- 資料庫伺服器:負責資料庫的運作
不過我們因為在練習開發,這三個全部都會發生在自己電腦上。
註 原本我把報名資料建立在Regist資料表中,不過我後來想想應該要叫Member資料表,等等會先教怎改資料表名稱
表單填寫資料存入資料表大致流程(規格書的版本)
通常開發規格書如果SA(系統分析師)跟PM(專案經理)沒有偷懶,每個流程都會有流程圖,大概會長這樣。
規格書上的流程會類似這樣,方形的都是要做什麼事情,菱形則是決策點,圈圈是開始跟結束,注意流程通常會是單向。
改資料表名稱
一樣開啟SSMS
使用SSMS登入資料庫
資料庫 > PartyRegister > 資料表Regist > 滑鼠右鍵點擊 > 重新命名
輸入新名稱Member
,然後按下Enter
這樣就完成了,SSMS可以先不用關閉,等下會用到。
開啟PartyRegister專案
如果你是好幾天前練習,已經把Visual Studio專案關了,我們需要重新把專案開啟
開啟Register.aspx
因為這篇文章是新手向的,所以我寫得仔細一些,我們現在要開啟Register.aspx
,檔案可以在右邊的方案總管找到,點兩下就會在左邊大畫面顯示出Register.aspx
的程式碼
然後在方案總管那邊,Regist.aspx
前面有個小三角形可以點下去,點下去後會顯示另外兩個檔案
Regist.aspx.cs
這個是C#檔案,會在伺服器端執行的。Regist.aspx.designer.cs
,這是給設計工具用的檔案,現在的開發通常長不使用設計工具了。
Regist.aspx 送出報名加上onClick
在之前的教學當中,我們已經完成Regist.aspx
畫面上的元件。
現在我們要將填寫資料送去伺服器,在送出按鈕上新增一個點擊事件OnClick
找到送出報名的按鈕>在屬性 輸入OnClick=""
選擇Create New Event
,新增後你的按鈕應該如下。
<asp:Button ID="btnSubmit" CssClass="btn btn-primary" Text="送出報名" runat="server" OnClick="btnSubmit_OnClick"/>
如果沒有出現Create New Event
(如果有裝Resharper 會變成Create method
),也可以直接輸入OnClick="btnSubmit_OnClick"
Regist.aspx.cs 寫入資料庫
老鳥應該有發現,我們還沒設定專案的資料庫連線,這個晚點我們等等新增。
開啟Regist.aspx.cs
- 從方案總管開啟需要點
Regist.aspx
左邊的小三角形才能看到Regist.aspx.cs
,滑鼠點兩下可以直接開 - 或者從
Regist.aspx
的程式碼畫面直接按F7
,就能直接開啟對應的.cs檔。
如果使用Create New Evnet會自動幫你新增在檔案中,若沒出現這個Method沒有我們也可以自己輸入
protected void btnSubmit_Click(object sender, EventArgs e)
{
}
再來終於可以開始寫程式了(?)
新手我們可以先在程式碼上用註解列一下要做什麼
protected void btnSubmit_Click(object sender, EventArgs e)
{
//TODO:
//1. 讀取表單資料到變數中
//2. 檢查資料是否完備(先略過)
//3. 讀取資料庫連線設定
//4. 開啟資料庫連線
//5. 執行寫入
//6. 關閉連線
}
接下來我們直接看程式碼就好
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
//1. 讀取表單資料到變數中
//姓名
string name = tbName.Text;
//性別
//讀進來的是字串,要轉成數字
int gender = int.Parse(rbGender.SelectedValue);
//生日
string birthday = tbBirthday.Text;
//Email
string email = tbEmail.Text;
//中華民國身分證字號
string rocID = tbROCID.Text;
string phone = tbPhone.Text;
//飲食習慣
string food = rbFood.SelectedValue;
//讀進來的是字串,要轉成數字
int eventId = int.Parse(rbEventId.SelectedValue);
//TODO:
//2. 檢查資料是否完備(先略過)
//3. 讀取資料庫連線設定
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (var conn = new SqlConnection(connStr))
{
//4. 開啟資料庫連線
conn.Open();
//5. 執行寫入
//SQL指令
string sql = @"Insert into Member (Name,Gender,Birthday,Email,RocID,Food,EventId,Phone,CreateTime)
values (@Name,@Gender,@Birthday,@Email,@RocID,@Food,@EventId,@Phone,@CreateTime)";
using (var cmd = new SqlCommand(sql, conn))
{
//設定參數 (切記 寫入資料庫一定要用參數)
//參數名稱要跟SQL指令中的參數名稱一樣
cmd.Parameters.AddWithValue("@Name", name);
cmd.Parameters.AddWithValue("@Gender", gender);
cmd.Parameters.AddWithValue("@Birthday", birthday);
cmd.Parameters.AddWithValue("@Email", email);
cmd.Parameters.AddWithValue("@RocID", rocID);
cmd.Parameters.AddWithValue("@Food", food);
cmd.Parameters.AddWithValue("@EventId", eventId);
cmd.Parameters.AddWithValue("@Phone", phone);
//報名時間
cmd.Parameters.AddWithValue("@CreateTime", DateTime.Now);
cmd.ExecuteNonQuery();
}
//6. 關閉資料庫連線 但因為使用using語法,所以不用寫
}
程式碼的補充說明:
- 有些書會教用Visual Studio的精靈配合
DataSource
直接設定好上面整串流程,不過實務上那個精靈工程師不太用。 - 舊的寫法會用
conn.Close();
conn.Disposed();
這兩個指令去關閉料庫連線,不過我們現在有using (var conn = new SqlConnection(connStr)){.....}
可以自動幫我們做這件事。 - 有些老書在SQL那邊會教直接用SQL組合值的寫法,這個極度不安全,千萬別這樣做。
//錯誤寫法 會有嚴重資安問題(sql injection)
string sql = @"Insert into Member (Name,Gender,Birthday,Email,RocID,Food,EventId,CreateTime)
values ("+ name +"," + gender + ","+ birthday + .....(略).....)";
這種作法是字串串接
加入連線字串
.Net Framwork網站的連線字串99%都寫在web.config這個檔案中,但新專案內檔案不會有這個設定,要自己加入。
點擊web.config開啟檔案
我們加入框起來這一整段,程式碼在下面
加入SQL SERVER Connection String
<connectionStrings>
<add name="DefaultConnection" connectionString="data source='.';initial catalog='PartyRegister';User Id='PartyRegister';Password='PartyRegister';" providerName="System.Data.SqlClient" />
</connectionStrings>
SQL SERVER Connection String範例說明
我把每個參數代表的值都放在下面了,請自行參考,如果網頁跟資料庫在同一台電腦可以在IP的地方直接輸入.
,如果不同台通常會輸入IP
<add name="連線名稱" connectionString="data source='資料庫IP';initial catalog='資料庫名稱';User Id='資料庫帳號';Password='資料庫密碼';" providerName="System.Data.SqlClient" />
測試資料庫寫入
接著切換回Regist.aspx,然後啟動網站
測試輸入資料的網頁有個重要技巧,我會依序用數字填入資料,這樣存入資料庫時候比較好比對那個欄位錯了。
填好資料後送出,如果沒問題的話,畫面只會閃一下又回到這個畫面,如果有問題會跳黃底的錯誤訊息。(有錯誤訊息可以把錯誤訊息+程式碼直接貼給ChatGPT比較快)
察看資料是否有存入資料庫
這時就要開啟SSMS,看一下剛剛填的資料有沒有存入
在SSMS內找到資料表,按右鍵 > 選取前1000個資料列
我因為有先刪除資料,所以資料很少。
這邊一定要對照一下資料有沒有存錯位置
驗證表單
對填寫資料的驗證相當必要,我這邊列一下各種欄位類型常見的驗證如下。這邊只有簡單列出一些比較常見的,至於每個欄位要驗證什麼就要靠自己想像(?)決定或問清楚,是否必填
因為是通用的,沒有列在表內。
資料類型 | 驗證項目 | HTML5欄位類型 | 常見欄位 |
---|---|---|---|
單選 | 選項範圍,輸入選項是否存在 | Radio / Select /CheckBox | 性別、飲食習慣、是/否 |
多選 | 已選項目數量,輸入選項是否存在 | CheckBox | |
單行文字 | 字串長度、內容格式 | TextBox | 姓名、地址、EMAIL、電話、電話、網址、身分證字號、電話號碼…等 |
多行文字 | 字串長度 | TextArea | 備註文字、文章內容 |
數字 | 範圍、是否允許小數點、正負數 | TextBox | 金額、數量 |
檔案 | 檔案類型、檔案大小、檔案數量 | File | 圖片、文件 |
日期 | 日期範圍、日期合理性、年齡限制 | TextBox | 起迄日、生日、建立日期、更新日期 |
時間 | 時間範圍、日期合理性 | TextBox | |
經緯度 | – | TextBox | 通常會配合地圖系統產生出對應的經緯度 |
新手可能會不知到什麼叫做「驗證輸入選項是否存在」,意思是假如性別輸入只能輸入男(1)、女(2),然後有個人透過網頁除錯模式改了一個A在性別欄位並送至後端,這時候後端要將輸入視為錯誤,因為沒有A這個選項,這種常見於駭客產生異常資料的作法。
文字欄位與驗證項目範例
文字類的欄位可以驗證的項目就非常多,很多表單的大宗欄位都是文字類型。
欄位 | 輸入範例 | 驗證項目 |
---|---|---|
姓名 | 歐大大 JOANNA 幾田 りら/いくた りら Bill Gates | 最少字數、最長字數、不可輸入數字、不可輸入特定符號!@#$%^ |
[email protected] | 要有@跟.,不能有一些特定字元#$%^&*()= 通常後續要透過信件驗證 | |
電話 | 07-111-2222 07-111-2222ext777 0910-000-000 | 要限定格式:手機or家電,實務上驗證比較複雜 |
網址 | https://www.google.com.tw | 要有http:// 或https:// 開頭,還要有. |
身份證字號 | A123456789 | 通用規則1英文字母+9個數字共10碼,精確作法則是要依照身份證字號規則計算出檢查碼。 |
地址 | 80203高雄市苓雅區四維三路2號 (這是高雄市政府) | 驗證地址必須包含關鍵字(縣市、地區)、驗證長度。 地址本身很難真的去限制格式。 如需要精確地址的系統會將地址中的郵遞區號、區、路、街、巷、弄、號、樓、之。分成各個文字欄位,各縣市的路、街本身有公開資料庫可以做成下拉選單。 |
生日欄位(日期欄位)
日期欄位可以輸入的坑也很多,沒規定的話日期輸入格式其實非常多元,實際上的作法是前端.aspx那邊要列出格式(或用日期選擇套件DatePicker),後端用DateTime.Tryparse()這個函數進行驗證
可能的輸入(正常的):
- 1991/1/10(年月日)
- 1/10/1999 (月日年,在某些國家是這種格式)
- 1 Jane 1999 (英文月)
- 1999年1月3日
- 1999-1-10
- 19990110
- 1999.1.10
- 1999.10.20
- 民國109.1.1
- 109.1.1 (也是民國)
- 99.1.1 (也是民國)
- 0990101 (也是民國)
- 2004/2/29(這一年有2/29日)
有沒有發現可以舉出一大堆都是日期輸入,甚至我遇過有些同一個系統的不同表單生日的日期系統是不同的…,有些地方是民國,有些是西元,有些國家有分不同的年號,像是日本有昭和、令和。
不正常的日期
- 1999/2/30 (2月沒有30日)
- 1999/4/31(4月沒有31日)
- 1999/2/29(該年度非潤年)
日期驗證除了需要驗證大小月以外,還需要驗證潤年。
這邊簡單的跟讓大家知道系統驗證上要思考些什麼,不過這個課程我們先驗證必填就好。
後端加上必填驗證 .aspx.cs
後端驗證是指.aspx那邊填寫完資料後,將資料送至btnSubmit_OnClick()
內,在存入資料庫前進行驗證,基本上現代的程式設計在前後端都需要進行驗證,但如果只選一個做的話,我會選後端。
實際做法:
- 建立一個
List<string>
存放錯誤訊息,errorMsg
List
是類似陣列的物件,可以透過Add()
增加項目,之後我們只需要判斷errorMsg
有沒有加入項目就能判斷驗證是否都通過。 - 文字類的驗證使用
string.IsNullOrEmpty()
這個函數,即使輸入為半形或全型空白都能視為沒輸入。 - 單選要轉換數字,使用int.TryParse()進行驗證
- 日期使用DateTime.TryParseExact 指定日期格式,
MM
是雙位數的月,dd
是雙位數的日,yyyy
則是四位數的西元
我們稍微改一下程式碼,一些需要轉換的部分改成在驗證時進行轉換。
//1. 讀取表單資料到變數中
//姓名
string name = tbName.Text;
//性別
int gender = 0;
//生日
DateTime birthday;
//Email
string email = tbEmail.Text;
//中華民國身分證字號
string rocID = tbROCID.Text;
//電話號碼
string phone = tbPhone.Text;
//飲食習慣
int food = 0;
//活動場次
int eventId = 0;
//2. 檢查資料是否完備
lbErrorMsg.Text = string.Empty;
List<string> errorMsg = new List<string>();
if (string.IsNullOrWhiteSpace(name))
{
errorMsg.Add("姓名必填");
}
if (!int.TryParse(rbGender.SelectedValue, out gender))
{
errorMsg.Add("性別必填");
}
if (string.IsNullOrWhiteSpace(phone))
{
errorMsg.Add("聯絡電話");
}
if (!DateTime.TryParseExact(tbBirthday.Text,"yyyy/MM/dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,out birthday))
{
tbBirthday.Text = "";
errorMsg.Add("生日必填");
}
if (string.IsNullOrWhiteSpace(rocID))
{
errorMsg.Add("身分證字號必填");
}
if (string.IsNullOrWhiteSpace(email))
{
errorMsg.Add("信箱必填");
}
if (!int.TryParse(rbFood.SelectedValue,out food))
{
errorMsg.Add("飲食習慣必填");
}
if (!int.TryParse(rbEventId.SelectedValue,out eventId))
{
errorMsg.Add("活動場次必填");
}
//如果上方的驗證不過,這邊會儲存錯誤訊息,因此會顯示錯誤訊息跟停止存檔
if (errorMsg.Any())
{
//顯示錯誤訊息
lbErrorMsg.Text = string.Join("、", errorMsg);
return;
}
測試必填驗證
測試必填驗證很簡單,就是什麼都不填寫直接按下確定。
(我發現送出報名沒有換行)
到目前的完整程式碼
這邊我有把錯誤訊息加上換行。
register.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Regist.aspx.cs" Inherits="PartyRegister.Regist" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>報名</h1>
<asp:Label ID="lbName" runat="server" Text="姓名"></asp:Label>
<asp:TextBox ID="tbName" runat="server"></asp:TextBox>
<br/>
<br/>
<asp:Label runat="server" ID="lbGender" Text="性別"></asp:Label>
<asp:RadioButtonList runat="server" ID="rbGender" RepeatDirection="Horizontal">
<asp:ListItem Text="男" Value="1"></asp:ListItem>
<asp:ListItem Text="女" Value="2"></asp:ListItem>
<asp:ListItem Text="其他" Value="3"></asp:ListItem>
</asp:RadioButtonList>
<br/>
<asp:Label ID="lbPhone" runat="server" Text="聯絡電話"></asp:Label>
<asp:TextBox ID="tbPhone" runat="server"></asp:TextBox>
<br/>
<asp:Label ID="lbBirthday" runat="server" Text="生日"></asp:Label>
<asp:TextBox ID="tbBirthday" runat="server"></asp:TextBox>
<br/>
<asp:Label ID="lbROCID" runat="server" Text="身分證字號"></asp:Label>
<asp:TextBox ID="tbROCID" runat="server"></asp:TextBox>
<br/>
<asp:Label ID="lbEmail" runat="server" Text="信箱"></asp:Label>
<asp:TextBox ID="tbEmail" runat="server"></asp:TextBox>
<br/>
<br/>
<asp:Label runat="server" ID="lbFood" Text="飲食"></asp:Label>
<asp:RadioButtonList runat="server" ID="rbFood" RepeatDirection="Horizontal">
<asp:ListItem Text="葷" Value="1"></asp:ListItem>
<asp:ListItem Text="素" Value="2"></asp:ListItem>
<asp:ListItem Text="其他" Value="3"></asp:ListItem>
</asp:RadioButtonList>
<br/>
<asp:Label runat="server" ID="lbEventId" Text="活動場次"></asp:Label>
<asp:RadioButtonList runat="server" ID="rbEventId" RepeatDirection="Horizontal">
<asp:ListItem Text="1月份" Value="1"></asp:ListItem>
<asp:ListItem Text="2月份" Value="2"></asp:ListItem>
<asp:ListItem Text="3月份" Value="3"></asp:ListItem>
</asp:RadioButtonList>
<br/>
<asp:Label runat="server" ID="lbErrorMsg" ForeColor="red"></asp:Label>
<br/>
<asp:Button ID="btnSubmit" CssClass="btn btn-primary" Text="送出報名" runat="server" OnClick="btnSubmit_OnClick"/>
</asp:Content>
register.aspx.cs
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PartyRegister
{
public partial class Regist : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
/// <summary>
/// 當按下送出按鈕 檢查表單內容 + 寫入資料庫
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
//1. 讀取表單資料到變數中
//姓名
string name = tbName.Text;
//性別
int gender = 0;
//生日
DateTime birthday;
//Email
string email = tbEmail.Text;
//中華民國身分證字號
string rocID = tbROCID.Text;
//電話號碼
string phone = tbPhone.Text;
//飲食習慣
int food = 0;
//活動場次
int eventId = 0;
//2. 檢查資料是否完備
lbErrorMsg.Text = string.Empty;
List<string> errorMsg = new List<string>();
if (string.IsNullOrWhiteSpace(name))
{
errorMsg.Add("姓名必填");
}
if (!int.TryParse(rbGender.SelectedValue, out gender))
{
errorMsg.Add("性別必填");
}
if (string.IsNullOrWhiteSpace(phone))
{
errorMsg.Add("聯絡電話");
}
if (!DateTime.TryParseExact(tbBirthday.Text,"yyyy/MM/dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,out birthday))
{
tbBirthday.Text = "";
errorMsg.Add("生日必填");
}
if (string.IsNullOrWhiteSpace(rocID))
{
errorMsg.Add("身分證字號必填");
}
if (string.IsNullOrWhiteSpace(email))
{
errorMsg.Add("信箱必填");
}
if (!int.TryParse(rbFood.SelectedValue,out food))
{
errorMsg.Add("飲食習慣必填");
}
if (!int.TryParse(rbEventId.SelectedValue,out eventId))
{
errorMsg.Add("活動場次必填");
}
//如果上方的驗證不過,這邊會儲存錯誤訊息,因此會顯示錯誤訊息跟停止存檔
if (errorMsg.Any())
{
//顯示錯誤訊息
lbErrorMsg.Text = string.Join("、", errorMsg);
return;
}
//3. 讀取資料庫連線設定
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (var conn = new SqlConnection(connStr))
{
//4. 開啟資料庫連線
conn.Open();
//5. 執行寫入
//SQL指令
string sql = @"Insert into Member (Name,Gender,Birthday,Email,RocID,Food,EventId,Phone,CreateTime)
values (@Name,@Gender,@Birthday,@Email,@RocID,@Food,@EventId,@Phone,@CreateTime)";
using (var cmd = new SqlCommand(sql, conn))
{
//設定參數 (切記 寫入資料庫一定要用參數)
//參數名稱要跟SQL指令中的參數名稱一樣
cmd.Parameters.AddWithValue("@Name", name);
cmd.Parameters.AddWithValue("@Gender", gender);
cmd.Parameters.AddWithValue("@Birthday", birthday);
cmd.Parameters.AddWithValue("@Email", email);
cmd.Parameters.AddWithValue("@RocID", rocID);
cmd.Parameters.AddWithValue("@Food", food);
cmd.Parameters.AddWithValue("@EventId", eventId);
cmd.Parameters.AddWithValue("@Phone", phone);
//報名時間
cmd.Parameters.AddWithValue("@CreateTime", DateTime.Now);
cmd.ExecuteNonQuery();
}
//6. 關閉資料庫連線 但因為使用using語法,所以不用寫
}
}
}
}
加入前端驗證
如果寫的網頁框架非Webform,前端驗證普遍是靠HTML5跟JavaScript在瀏覽器進行。如果是webform,則不太會自己寫JavaScript(原因是容易跟Webform自己產生的JavaScript產生衝突導致網頁無法送出…),主要是靠下面幾種類型
ASP:Textbox
: 設定TextMode
指定對應HTML5的input
去限制類型- Html 5 的一些限制標籤,常用的有
requird min max step
等 - Validator類,這是Webform內建的驗證,後來有Html 5後我就很少用了
CompareValidator
,我沒用過,官方文件CustomValidaor
自訂(跟後端串接驗證),這個比較有在使用,如果需要比較複雜的驗證就需要它,官方文件RegularExpressionValidator
,其中RegularExpression
是指正規表示法,簡稱Regex,Regex是一個可以告訴電腦要用怎樣的模式去驗證,像是前幾碼數字,後幾碼文字等,對新手偏難,建議可以直接請chatGpt產生就好。RangeValidator
(範圍限定) ,這個被min max step
屬性取代官方文件RequiredFieldValidator
(必填),這個被Html 5的requird
屬性取代,官方文件,不過如果要做checkbox跟radio的必填還是會使用它ValidationSummary
(驗證)官方文件
TEXTMODE
前文說到了TEXTMODE
是對應HTML的input type類型,使用這類input type要注意使用者的瀏覽器可能不支援,不過現代2025年使用舊版瀏覽器的環境其實非常少了。
我列一下我常用的
text
(預設是這個),可以配合maxlength
跟minlength
屬性限制長度。password
密碼,輸入會顯示*號。number
數字,可以配合min max 限制範圍,配合step屬性。email
信箱
可以用但不太用
date
日期選擇 ,通常都外掛Datetime Picker這個類型的外掛。time
時間選擇,通常都還是用其他外掛為主。tel
電話,這個格式複雜,通常用RegularExpress驗證為主,不過很多時候是配合簡訊驗證碼驗證號碼有效性。
不太用這幾個的原因是每個瀏覽器對於date的實作都不太一樣
加入required
屬性
在這個範例中,文字欄位使用required
進行必填驗證就好
把程式碼textbox
全部加入required
性別 飲食習慣 活動場次加入 RequiredFieldValidator
直接在rbGender
後加入這段程式碼
<asp:RequiredFieldValidator
ID="rfvGender"
runat="server"
ControlToValidate="rbGender"
InitialValue=""
ErrorMessage="請選擇性別"
ForeColor="Red"
Display="Dynamic" />
這邊照寫就好,
ID="rfvGender"
用rfv代表必填驗證,Gender是驗證項目ControlToValidate="rbGender"
要驗證的元件IDErrorMessage ="請選擇性別"
驗證失敗要顯示的訊息ForeColor="Red"
驗證失敗要顯示的訊息顏色
再來重新載入網頁測試效果
作業:加上其他驗證
程式碼
前端 Regist.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Regist.aspx.cs" Inherits="PartyRegister.Regist" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>報名</h1>
<asp:Label ID="lbName" runat="server" Text="姓名"></asp:Label>
<asp:TextBox ID="tbName" runat="server" required></asp:TextBox>
<br/>
<br/>
<asp:Label runat="server" ID="lbGender" Text="性別"></asp:Label>
<asp:RadioButtonList runat="server" ID="rbGender" RepeatDirection="Horizontal" >
<asp:ListItem Text="男" Value="1"></asp:ListItem>
<asp:ListItem Text="女" Value="2"></asp:ListItem>
<asp:ListItem Text="其他" Value="3"></asp:ListItem>
</asp:RadioButtonList>
<asp:RequiredFieldValidator
ID="rfvGender"
runat="server"
ControlToValidate="rbGender"
InitialValue=""
ErrorMessage="請選擇性別"
ForeColor="Red"
Display="Dynamic" />
<br/>
<asp:Label ID="lbPhone" runat="server" Text="聯絡電話"></asp:Label>
<asp:TextBox ID="tbPhone" runat="server" required></asp:TextBox>
<br/>
<asp:Label ID="lbBirthday" runat="server" Text="生日"></asp:Label>
<asp:TextBox ID="tbBirthday" runat="server" required></asp:TextBox>
<br/>
<asp:Label ID="lbROCID" runat="server" Text="身分證字號"></asp:Label>
<asp:TextBox ID="tbROCID" runat="server" required></asp:TextBox>
<br/>
<asp:Label ID="lbEmail" runat="server" Text="信箱"></asp:Label>
<asp:TextBox ID="tbEmail" runat="server" required></asp:TextBox>
<br/>
<br/>
<asp:Label runat="server" ID="lbFood" Text="飲食"></asp:Label>
<asp:RadioButtonList runat="server" ID="rbFood" RepeatDirection="Horizontal">
<asp:ListItem Text="葷" Value="1"></asp:ListItem>
<asp:ListItem Text="素" Value="2"></asp:ListItem>
<asp:ListItem Text="其他" Value="3"></asp:ListItem>
</asp:RadioButtonList>
<asp:RequiredFieldValidator
ID="rfvFood"
runat="server"
ControlToValidate="rbFood"
InitialValue=""
ErrorMessage="請選擇飲食"
ForeColor="Red"
Display="Dynamic" />
<br/>
<asp:Label runat="server" ID="lbEventId" Text="活動場次"></asp:Label>
<asp:RadioButtonList runat="server" ID="rbEventId" RepeatDirection="Horizontal">
<asp:ListItem Text="1月份" Value="1"></asp:ListItem>
<asp:ListItem Text="2月份" Value="2"></asp:ListItem>
<asp:ListItem Text="3月份" Value="3"></asp:ListItem>
</asp:RadioButtonList>
<asp:RequiredFieldValidator
ID="rfvEventId"
runat="server"
ControlToValidate="rbFood"
InitialValue=""
ErrorMessage="請選擇活動場次"
ForeColor="Red"
Display="Dynamic" />
<br/>
<asp:Label runat="server" ID="lbErrorMsg" ForeColor="red"></asp:Label>
<br/>
<asp:Button ID="btnSubmit" CssClass="btn btn-primary" Text="送出報名" runat="server" OnClick="btnSubmit_OnClick"/>
</asp:Content>
後端 Regist.aspx.cs
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PartyRegister
{
public partial class Regist : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
/// <summary>
/// 當按下送出按鈕 檢查表單內容 + 寫入資料庫
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnSubmit_OnClick(object sender, EventArgs e)
{
//1. 讀取表單資料到變數中
//姓名
string name = tbName.Text;
//性別
int gender = 0;
//生日
DateTime birthday;
//Email
string email = tbEmail.Text;
//中華民國身分證字號
string rocID = tbROCID.Text;
//電話號碼
string phone = tbPhone.Text;
//飲食習慣
int food = 0;
//活動場次
int eventId = 0;
//2. 檢查資料是否完備
lbErrorMsg.Text = string.Empty;
List<string> errorMsg = new List<string>();
if (string.IsNullOrWhiteSpace(name))
{
errorMsg.Add("姓名必填");
}
if (!int.TryParse(rbGender.SelectedValue, out gender))
{
errorMsg.Add("性別必填");
}
if (string.IsNullOrWhiteSpace(phone))
{
errorMsg.Add("聯絡電話");
}
if (!DateTime.TryParseExact(tbBirthday.Text,"yyyy/MM/dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,out birthday))
{
tbBirthday.Text = "";
errorMsg.Add("生日必填");
}
if (string.IsNullOrWhiteSpace(rocID))
{
errorMsg.Add("身分證字號必填");
}
if (string.IsNullOrWhiteSpace(email))
{
errorMsg.Add("信箱必填");
}
if (!int.TryParse(rbFood.SelectedValue,out food))
{
errorMsg.Add("飲食習慣必填");
}
if (!int.TryParse(rbEventId.SelectedValue,out eventId))
{
errorMsg.Add("活動場次必填");
}
//如果上方的驗證不過,這邊會儲存錯誤訊息,因此會顯示錯誤訊息跟停止存檔
if (errorMsg.Any())
{
//顯示錯誤訊息
lbErrorMsg.Text = string.Join("、", errorMsg);
return;
}
//3. 讀取資料庫連線設定
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (var conn = new SqlConnection(connStr))
{
//4. 開啟資料庫連線
conn.Open();
//5. 執行寫入
//SQL指令
string sql = @"Insert into Member (Name,Gender,Birthday,Email,RocID,Food,EventId,Phone,CreateTime)
values (@Name,@Gender,@Birthday,@Email,@RocID,@Food,@EventId,@Phone,@CreateTime)";
using (var cmd = new SqlCommand(sql, conn))
{
//設定參數 (切記 寫入資料庫一定要用參數)
//參數名稱要跟SQL指令中的參數名稱一樣
cmd.Parameters.AddWithValue("@Name", name);
cmd.Parameters.AddWithValue("@Gender", gender);
cmd.Parameters.AddWithValue("@Birthday", birthday);
cmd.Parameters.AddWithValue("@Email", email);
cmd.Parameters.AddWithValue("@RocID", rocID);
cmd.Parameters.AddWithValue("@Food", food);
cmd.Parameters.AddWithValue("@EventId", eventId);
cmd.Parameters.AddWithValue("@Phone", phone);
//報名時間
cmd.Parameters.AddWithValue("@CreateTime", DateTime.Now);
cmd.ExecuteNonQuery();
}
//6. 關閉資料庫連線 但因為使用using語法,所以不用寫
}
}
}
}
0 Comments