🌵 建立 Dealer Manager - Content Page 後台頁面 - 代理商功能。
📌 後台代理商功能需要的功能如下 :
🌵 灰色欄位設定為 ReadOnly,無法修改。
🌵 這個區域資料較多,Visible 先設成 false 不顯示,選完國家及代理商後才顯示。
👺 代理商的 Thumbnail 縮圖建議用 asp:Literal 控制項送 HTML 的作法製作,如果使用 asp:Image 控制項,在圖檔名稱有中文時,後端使用 .ImageUrl 設定控制項路徑,會在渲染後因為中文轉碼而讀不到圖片。
🧠 可以在資料庫圖表的關聯性中設定屬性,將關聯性 " INSERT 及 UPDATE 規格" 裡面的刪除規則,設定為串聯刪除 (**重疊顯示 - Cascade **),這樣如果刪除國家時,會一併刪除該國的區域代理商,可以避免手殘亂刪時出現錯誤,當然也會寫在後台的規則裡。
👀 串聯刪除-設定參考 : 如何在 SQL Server 資料庫設計「一對一」表格關聯
🌵 先在原始檔頁選擇點選控制項該行程式碼,再轉到設計頁可以避免選錯,點擊側開選項設定資料來源時,要勾 countrySort 跟 id 這樣設定完成後,再點擊側開選項選擇資料來源時,資料欄位值才能選到 id。
👺 這裡很重要,有設定的話 SQL 語法會變很簡單,後面有遇到下拉選單最好都設定。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
DropDownList1.DataBind(); //先綁定取得選取預設值
showDealerList();
}
}
private void showDealerList()
{
//依下拉選單選取國家的值 (id) 取得地區分類
string selCountry_id = DropDownList1.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = "SELECT area FROM Dealers WHERE country_ID = @selCountry_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@selCountry_id", selCountry_id);
//取得地區分類
connection.Open();
SqlDataReader readerCountry = command.ExecuteReader();
while (readerCountry.Read()) {
string typeStr = readerCountry["area"].ToString();
// RadioButtonList 增加方式
ListItem listItem = new ListItem();
listItem.Text = typeStr;
listItem.Value = typeStr;
RadioButtonList1.Items.Add(listItem);
}
connection.Close();
}
protected void BtnAddArea_Click(object sender, EventArgs e)
{
//取得下拉選單國家的值 (id)
string selCountry_id = DropDownList1.SelectedValue;
//取得輸入欄內的文字
string areaStr = TBoxAddArea.Text;
//判斷是否重複用
bool isRepeat = false;
//取得地區分類
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = $"SELECT area FROM Dealers WHERE country_ID = @selCountry_id";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@selCountry_id", selCountry_id);
connection.Open();
SqlDataReader readerCountry = command.ExecuteReader();
while (readerCountry.Read()) {
string typeStr = readerCountry["area"].ToString();
//判斷有無重複名稱
if (areaStr.Equals(typeStr)) {
isRepeat = true;
//重複警告
TBoxAddArea.ForeColor = Color.Red;
TBoxAddArea.Text = "The area name is repeated!";
}
}
connection.Close();
//輸入的區域名稱不重複才執行
if (!isRepeat) {
TBoxAddArea.ForeColor = Color.Black;
//新增區域
string sql2 = "INSERT INTO Dealers (country_ID, area) VALUES(@selCountry_id, @areaStr)";
SqlCommand command2 = new SqlCommand(sql2, connection);
command2.Parameters.AddWithValue("@selCountry_id", selCountry_id);
command2.Parameters.AddWithValue("@areaStr", areaStr);
connection.Open();
command2.ExecuteNonQuery();
connection.Close();
//畫面渲染
RadioButtonList1.Items.Clear(); //清掉舊的
BtnDelArea.Visible = false;
DealerList.Visible = false;
LabUploadImg.Visible = false;
UpdateDealerListLab.Visible = false;
showDealerList(); //讀取新的
//清空輸入欄位
TBoxAddArea.Text = "";
}
}
protected void BtnDelArea_Click(object sender, EventArgs e)
{
//取得選取資料的值
string selAreaStr = RadioButtonList1.SelectedValue;
//刪除實際圖檔檔案
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = "SELECT dealerImgPath FROM Dealers WHERE area = @selAreaStr";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@selAreaStr", selAreaStr);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.Read()) {
string imgPath = reader["dealerImgPath"].ToString();
if (!imgPath.Equals("")) {
string savePath = Server.MapPath($"~/Tayanahtml/upload/Images/{imgPath}");
File.Delete(savePath);
}
}
connection.Close();
//刪除資料庫該筆資料
string sqlDel = "DELETE FROM Dealers WHERE area = @selAreaStr";
SqlCommand commandDel = new SqlCommand(sqlDel, connection);
commandDel.Parameters.AddWithValue("@selAreaStr", selAreaStr);
connection.Open();
commandDel.ExecuteNonQuery();
connection.Close();
//畫面渲染
RadioButtonList1.Items.Clear(); //清掉舊的
BtnDelArea.Visible = false;
DealerList.Visible = false;
LabUploadImg.Visible = false;
UpdateDealerListLab.Visible = false;
showDealerList(); //讀取新的
TBoxAddArea.ForeColor = Color.Black;
TBoxAddArea.Text = "";
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
//當選擇國家改變時刷新畫面資料
RadioButtonList1.Items.Clear();
BtnDelArea.Visible = false;
DealerList.Visible = false;
LabUploadImg.Visible = false;
UpdateDealerListLab.Visible = false;
showDealerList();
}
AutoPostBack="True"
,這樣選取改變時才會刷新頁面。private void showDealerListTable()
{
//當區域選取時才顯示代理商資料表
DealerList.Visible = true;
//放入國家顯示文字
TBoxCountry.Text = DropDownList1.SelectedItem.Text;
//放入區域
TBoxArea.Text = RadioButtonList1.SelectedValue;
//依選取區域的值連接資料庫取得資料
string selAreaStr = RadioButtonList1.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = $"SELECT * FROM Dealers WHERE area = @selAreaStr";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@selAreaStr", selAreaStr);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
//放入個別資料
while (reader.Read()) {
string savePath = reader["dealerImgPath"].ToString();
LiteralImg.Text = $"<img alt='Thumbnail Image' src='/Tayanahtml/upload/Images/{savePath}' Width='209px'/>";
TBoxImage.Text = reader["dealerImgPath"].ToString();
TBoxName.Text = reader["name"].ToString();
TBoxContact.Text = reader["contact"].ToString();
TBoxAddress.Text = reader["address"].ToString();
TBoxTel.Text = reader["tel"].ToString();
TBoxFax.Text = reader["fax"].ToString();
TBoxEmail.Text = reader["email"].ToString();
TBoxLink.Text = reader["link"].ToString();
TBoxDate.Text = reader["initDate"].ToString();
}
connection.Close();
}
🌵 用 .SelectedItem.Text 來取得下拉選單選取的顯示文字 !
🌵 圖片路徑 savePath 是用來送到前台的 HTML 內容,所以前面不是波浪符號喔 !
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
//區域預設不選取,但當選取切換時顯示刪除按鈕
BtnDelArea.Visible = true;
LabUploadImg.Visible = false;
UpdateDealerListLab.Visible = false;
//顯示區域代理商資料表
showDealerListTable();
TBoxAddArea.ForeColor = Color.Black;
TBoxAddArea.Text = "";
}
AutoPostBack="True"
,這樣選取改變時才會刷新頁面。protected void BtnUploadImg_Click(object sender, EventArgs e)
{
//設定存檔路徑,需填完整路徑,結尾反斜線如果沒加要用 Path.Combine() 可自動添加
string savePath = Server.MapPath("~/Tayanahtml/upload/Images/");
//判斷有選檔案才可上傳
if (FileUpload1.HasFile) {
//取得選擇區域名稱
string selAreaStr = RadioButtonList1.SelectedValue;
//先執行刪除舊圖檔
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sqlDel = "SELECT dealerImgPath FROM Dealers WHERE area = @selAreaStr";
SqlCommand commandDel = new SqlCommand(sqlDel, connection);
commandDel.Parameters.AddWithValue("@selAreaStr", selAreaStr);
connection.Open();
SqlDataReader reader = commandDel.ExecuteReader();
if (reader.Read()) {
string delFileName = reader["dealerImgPath"].ToString();
//有舊圖才執行刪除
if (!String.IsNullOrEmpty(delFileName)) {
File.Delete(savePath + delFileName);
}
}
connection.Close();
//儲存圖片檔案及圖片名稱
//檢查專案資料夾內有無同名檔案,有同名就加流水號
DirectoryInfo directoryInfo = new DirectoryInfo(savePath);
//取得選取檔案名稱
string fileName = FileUpload1.FileName;
string[] fileNameArr = fileName.Split('.');
int count = 0;
foreach (var fileItem in directoryInfo.GetFiles()) {
if (fileItem.Name.Contains(fileNameArr[0])) {
count++;
}
}
fileName = fileNameArr[0] + $"({count + 1})." + fileNameArr[1];
FileUpload1.SaveAs(savePath + fileName);
//渲染畫面
DateTime nowtime = DateTime.Now;
LabUploadImg.Visible = true;
LabUploadImg.ForeColor = Color.Green;
LabUploadImg.Text = "*Upload Success! - " + nowtime.ToString("G");
//更新資料庫資料
string sql = "UPDATE Dealers SET dealerImgPath = @fileName WHERE area = @selAreaStr";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@fileName", fileName);
command.Parameters.AddWithValue("@selAreaStr", selAreaStr);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
//渲染畫面
showDealerListTable();
}
else {
//警告沒有選取檔案
LabUploadImg.Visible = true;
LabUploadImg.ForeColor = Color.Red;
LabUploadImg.Text = "*Need Choose File!";
}
}
👀 DirectoryInfo 類別參考官網 : DirectoryInfo 類別
👀 GetFiles() 方法參考官網 : DirectoryInfo.GetFiles 方法
🌵 用 .Contains 才能把已經加過流水號的檔案算進計算的數量裡。
🌵 FileUpload 控制項需配合一個按鈕控制項來執行上傳功能。
👺 儲存圖檔前記得先檢查有無同名檔案,而且檢查圖檔要針對存放的資料夾,因為可能會出現同名但內容不同的圖片,避免其它頁面有使用同名檔案被取代。
protected void BtnUpdateDealerList_Click(object sender, EventArgs e)
{
//依國家及選取區域的值連接資料庫取得資料
string selAreaStr = RadioButtonList1.SelectedValue;
string selCountry_id = DropDownList1.SelectedValue;
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
string sql = $"UPDATE Dealers SET name=@name, contact=@contact, address=@address, tel=@tel, fax=@fax, email=@email, link=@link WHERE country_ID=@selCountry_id AND area = @selAreaStr";
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@name", TBoxName.Text);
command.Parameters.AddWithValue("@contact", TBoxContact.Text);
command.Parameters.AddWithValue("@address", TBoxAddress.Text);
command.Parameters.AddWithValue("@tel", TBoxTel.Text);
command.Parameters.AddWithValue("@fax", TBoxFax.Text);
command.Parameters.AddWithValue("@email", TBoxEmail.Text);
command.Parameters.AddWithValue("@link", TBoxLink.Text);
command.Parameters.AddWithValue("@selCountry_id", selCountry_id);
command.Parameters.AddWithValue("@selAreaStr", selAreaStr);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
//渲染上傳成功提示
DateTime nowtime = DateTime.Now;
UpdateDealerListLab.Visible = true;
UpdateDealerListLab.Text = "*Upload Success! - " + nowtime.ToString("G");
Page.SetFocus(UpdateDealerListLab);
}
13. 渲染畫面後,進行功能測試,確認無誤,完成此頁後台功能~
📢 這個頁面因為放入兩組會互相影響的功能,所以關鍵會在互動時的項目開關,如上篇提到的增刪國家時,國家下拉選單要同步更新,而在下拉選取不同國家時預設不選取任何區域,是避免反覆讀取還不確定使用者要看的資料是哪個,而在選取區域後會秀出刪除區域的按鈕,刪除區域後又會回到預設不選取任何區域,另外選取區域後才會秀出這個國家這個區域的代理商細項資料,這些切換的細節,在第一次設計畫面交互時可能不太好想到,可以試著先畫草稿模擬想像。