走過了前端的一些坑之後接著來處理後端的功能,相較於前端開發完後在瀏覽器可以看到即時的結果(例如場景有沒有正常載入),傳到server的部分就常常要將處理的行為在編輯器(Visual Studio)下斷點看輸出的數值(下log也可以,但自己的習慣是斷點逐步執行的過程中確定功能input到output跟自己想的一樣)。
第二天分享的內容主要會環繞在前端怎麼傳資料到後端、Web Service的使用方式以及資料庫端的簡單概念,並且接下來分享的技術和工具都是主要使用到的。
AJAX即「Asynchronous JavaScript and XML」(非同步的JavaScript與XML技術),指的是一套綜合了多項技術的瀏覽器端網頁開發技術。
開發情境 : 今天使用者輸入一些資訊後接著做查詢或者是登入的動作,接著按下確認鍵後的處裡過程,而首先會有一個鍵的表單並且按鍵加入onclick的行為去呼叫執行ajax的動作。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/action_page.php">
<input type="text" id="account" name="account" value="John"><br>
<input type="text" id="password" name="password" value="Doe"><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
<button type="button" value="確認" onclick="LoginCheck()">
Ajax呼叫的範例如下(以Jquery為例)可以看到裡面有幾個重要的參數,首先是url為呼叫的指定位置指定要做甚麼事情,接著資料要傳什麼則是放在data這裡面(如果要傳的內容較多建議存成json的型態)。
function LoginCheck(){
$.ajax({
type: 'GET', // 用POST or GET的方式
dataType: 'json', // 資料的格式
url: url, // 呼叫後端的URL
data: data, // 傳送給後端的資料
timeout: 5000,
async: false, // 是否開啟同步非同步請求
success: function(data, textStatus ){ // 成功回傳結果
alert('request successful');
},
fail: function(xhr, textStatus, errorThrown){ // 失敗回傳結果
alert('request failed');
}
});
}
後端的處理上依照先前長期合作單位使用Web Service的sample code進行修改(整個專案是使用ASP.NET Web Forms),那時候還很好笑的詢問提供程式碼的聯絡窗口哪裡可以看到後端的處理行為xD
.ASMX 提供的功能可讓您建立 web 服務,使用簡單的物件存取通訊協定 (SOAP) 傳送訊息。SOAP 是一種與平臺無關且與語言無關的通訊協定,可用於建立及存取 web 服務。.ASMX 服務的取用者不需要知道用來執行此服務的平臺、物件模型或程式設計語言的任何相關資訊。
//首頁登入按鈕(點擊後登入成功刷新頁面)
//登入按鈕
function LoginCheck(){
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebService.asmx/ValidateLogin",
data: "{'username':'" + $('#account').val() + "','userpwd':'" + $('#password').val() + "'}",
dataType: "json",
async: false,
success: function (result) {
if (result.d == false) {
bootbox.alert({
size: "small", title: "訊息提示", message: "帳號密碼錯誤!",
callback: function () {
}
});
} else {
$('#divlogout1').removeClass('hidden');
$('#divlogin1').addClass('hidden');
// 成功登入後刷新訂單
$('#order-list').load(' #order-list > *');
//$('#btnSubmit').load(' #btnSubmit');
$('#btnSubmit').css('display', 'block');
// 20200615--test
//$('#goto3dreality').load(' #goto3dreality > *');
}
},
fail: function(xhr, textStatus, errorThrown){ // 失敗回傳結果
alert('request failed');
}
});
});
以下為登入的判斷行為
using DBAction;
using Ini;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Web;
using System.Web.Services;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// 若要允許使用 ASP.NET AJAX 從指令碼呼叫此 Web 服務,請取消註解下列一行。
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService
{
#region 會員登入
[WebMethod(EnableSession = true)]
public bool ValidateLogin(string username, string userpwd)
{
// 授權:設定角色到 userData
//userData = "gold_member,board_admin";
using (SqlCommand Cmd = new SqlCommand())
{
bool _tf = false;
Cmd.CommandText = "SELECT UserName,EMail,UserId FROM [MemberInfo] WHERE [Email]=@Email AND [LoginPwd]=@LoginPwd AND IsDel=0 ";
Cmd.Parameters.AddWithValue("@Email", username);
Cmd.Parameters.AddWithValue("@LoginPwd", userpwd);
DataTable dt = dbCommand.GetTable(Cmd);
if (dt.Rows.Count > 0)
{
_tf = true;
HttpContext.Current.Session.Add("userid", dt.Rows[0][2].ToString());
HttpContext.Current.Session.Add("username", dt.Rows[0][0].ToString());
}
return _tf; // JsonConvert.SerializeObject(_tf);
}
}
#endregion
}
例外補充當執行資料表指令前需要連線到資料庫(當時是分開做處理)。
DataTable dt = dbCommand.**GetTable**(Cmd);
public static DataTable GetTable(SqlCommand command)
{
DataTable data = new DataTable();
using (SqlConnection sqlconnection = new SqlConnection(WebConfigurationManager.ConnectionStrings["ptri219"].ConnectionString))
{
command.Connection = sqlconnection;
using (SqlDataAdapter Sqla = new SqlDataAdapter(command))
{
Sqla.Fill(data);
}
}
return data;
}
綜合上述基本上大概流程會這樣
與昨天的前端篇一起檢視開發上可以留意的幾點
原本想要把資料庫這塊寫在今天,但這兩天超級濃縮將前後端處理的過程寫完後直接打消這個念頭xD,明天則是會延伸討論資料庫的指令以及網站上線的處理細節。