溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于MVC4+EasyUI的Web開發(fā)框架形成之旅--基類控制器CRUD的操作

發(fā)布時間:2020-07-12 16:03:04 來源:網(wǎng)絡 閱讀:345 作者:wuhuacong 欄目:開發(fā)技術

在上一篇隨筆中,我對Web開發(fā)框架的總體界面進行了介紹,其中并提到了我的《Web開發(fā)框架》的控制器的設計關系,Web開發(fā)框架沿用了我的《Winform開發(fā)框架》的很多架構設計思路和特點,對Controller進行了封裝。使得控制器能夠獲得很好的繼承關系,并能以更少的代碼,更高效的開發(fā)效率,實現(xiàn)Web項目的開發(fā)工作,整個控制器的設計思路如下所示。

基于MVC4+EasyUI的Web開發(fā)框架形成之旅--基類控制器CRUD的操作

從上圖的設計里面可以看到,我把主要能通過抽象封裝的CRUD方法都放到了BusinessController<B, T>類里面,本文繼續(xù)詳細介紹這個Web框架控制器類的CRUD具體實現(xiàn),以便使得大家了解我的整個Web開發(fā)框架的基類控制器的工作原理。

1、基類的插入操作

我們知道,一般常規(guī)的插入操作是很普遍的操作,那么我們在MVC的Web界面上是如何調(diào)用的,后臺又是如何進行數(shù)據(jù)的處理的呢?

在MVC的View視圖代碼里面,我們添加數(shù)據(jù)的時候,javascript腳本代碼是這樣的:

var postData = $("#ffAdd").serializeArray();
$.post("/Information/Insert", postData, function (data) {
	if (data = "true") {
		//添加成功  1.關閉彈出層,2.刷新DataGird
		$.messager.alert("提示", "添加成功");
		$("#DivAdd").dialog("close");
		$("#grid").datagrid("reload");
		$("#ffAdd").form("clear");

		//本頁面的類型為【通知公告】,固定不變
		$("#Category").val("通知公告");
	}
	else {
		$.messager.alert("提示", "添加失敗,請您檢查");
	}
});

其中的serializeArray就把該表單要提交的數(shù)據(jù)序列號到一個字符串里面了,里面的數(shù)據(jù)可能類似A=a&B=b&C=c 這樣的字符串里面了,通過POST調(diào)用控制器Information的Insert方法,實現(xiàn)數(shù)據(jù)的插入。由于控制器Information是具體業(yè)務類,因此它繼承自BusinessController<B, T>,也就是會調(diào)用BusinessController<B, T>控制器的Insert方法。

如字典數(shù)據(jù)添加的界面如下所示。

基于MVC4+EasyUI的Web開發(fā)框架形成之旅--基類控制器CRUD的操作

那么后臺的接收方法如何呢?其實后臺是把數(shù)據(jù)序列化到了一個FormCollection對象的集合里面了,但是,我們還可以使用對象T(實體類),讓這些數(shù)據(jù)集合賦值給對應的實體對象屬性,如下就是我的后臺控制器的插入方法,它的參數(shù)是一個實體類T,這樣我們直接調(diào)用業(yè)務操作類就可以插入了,代碼很簡單易懂。

/// <summary>
/// 插入指定對象到數(shù)據(jù)庫中
/// </summary>
/// <param name="info">指定的對象</param>
/// <returns>執(zhí)行操作是否成功。</returns>
public virtual ActionResult Insert(T info)
{bool result = false;
	if (info != null)
	{
		result = baseBLL.Insert(info);
	}
	return Content(result);
}

2、基類的更新操作

上面我們看了插入數(shù)據(jù)的操作,可能大家對下面介紹的數(shù)據(jù)更新操作,可能也已經(jīng)有了一些了解了,其實它和插入操作的方法很類似的。

更新操作的視圖View中腳本代碼如下所示, 它通過控制器Information的Update方法進行更新數(shù)據(jù)。

var ID = $("#ID1").val();
var postData = $("#ffEdit").serializeArray();
$.post("/Information/Update?ID=" + ID, postData, function (date) {
	if (date == "true") {
		//修改成功,關閉彈出層,刷新DataGird
		$.messager.alert("提示", "修改成功");
		$("#DivEdit").dialog('close');
		$("#grid").datagrid("reload");
	}
	else {
		$.messager.alert("提示", "修改失敗,請您檢查");
	}
});

由于控制器Information是具體業(yè)務類,因此它繼承自BusinessController<B, T>,也就是會調(diào)用BusinessController<B, T>控制器的Update方法。

和上面的插入操作一樣,后臺是把數(shù)據(jù)序列化到了一個FormCollection對象的集合里面了,我們可以使用類似和插入方法的操作,如下所示。

/// <summary>
/// 更新對象屬性到數(shù)據(jù)庫中
/// </summary>
/// <param name="info">指定的對象</param>
/// <param name="id">主鍵ID的值</param>
/// <returns>執(zhí)行成功返回<c>true</c>,否則為<c>false</c>。</returns>
public virtual ActionResult Update(T info, string id)
{
	bool result = baseBLL.Update(info, id);
	return Content(result);
}

但是,如果使用以上的代碼作為更新數(shù)據(jù)的代碼,那么在編輯界面里,如果只是顯示編輯部分表的數(shù)據(jù),那么可能導致很多屬性會被初始化為實體類的默認值,顯然這樣不符合我們的要求,我們可能只是進行部分更新,那么我們進行部分更新的控制器方法應該如何設計呢?

前面我們說到,數(shù)據(jù)會被序列號到一個FormCollection對象集合里面,更新方法也一樣,那么我們可以把更新操作的接口定義為如下代碼所示,視圖操作代碼不變化:

/// <summary>
/// 更新對象屬性到數(shù)據(jù)庫中
/// </summary>
/// <param name="info">指定的對象</param>
/// <param name="id">主鍵ID的值</param>
/// <returns>執(zhí)行成功返回<c>true</c>,否則為<c>false</c>。</returns>
public virtual ActionResult Update(string id, FormCollection formValues)

我們可以通過調(diào)試的方法,查詢到FormCollection里面的值就是我們更新界面里面的數(shù)據(jù)(注意:可能是實體類的部分數(shù)據(jù))。但使用了這個方法后,我們還需要把FormCollection對象里面的數(shù)據(jù)轉(zhuǎn)換為實體類的信息,我們才好調(diào)用BaseBLL里面的接口進行更新數(shù)據(jù)。但是不同的實體類,有不同的屬性,我們?nèi)绾文軌虺橄蟀阉麄兊膶傩远假x值了呢?

答案是通過反射屬性方式,把FormCollection里面屬性的值賦值給對應實體類屬性的值。下面我們來介紹下具體的代碼實現(xiàn)了。

/// <summary>
/// 更新對象屬性到數(shù)據(jù)庫中
/// </summary>
/// <param name="info">指定的對象</param>
/// <param name="id">主鍵ID的值</param>
/// <returns>執(zhí)行成功返回<c>true</c>,否則為<c>false</c>。</returns>
public virtual ActionResult Update(string id, FormCollection formValues)
{

	T obj = baseBLL.FindByID(id);
	if (obj != null)
	{
		//遍歷提交過來的數(shù)據(jù)(可能是實體類的部分屬性更新)
		foreach (string key in formValues.Keys)
		{
			string value = formValues[key];
			System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(key);
			if (propertyInfo != null)
			{
				try
				{
					// obj對象有key的屬性,把對應的屬性值賦值給它(從字符串轉(zhuǎn)換為合適的類型)
					//如果轉(zhuǎn)換失敗,會拋出InvalidCastException異常
					propertyInfo.SetValue(obj, Convert.ChangeType(value, propertyInfo.PropertyType), null);
				}
				catch { }
			}
		}
	}

	bool result = baseBLL.Update(obj, id);
	return Content(result);
}

通過對象propertyInfo的SetValue方法,可以把字符串的值,轉(zhuǎn)換為實體類對應屬性類型的值,順利進行賦值。

如果是業(yè)務類需要提交一些HTML的代碼,那么我們需要在具體的業(yè)務類里面,重寫插入、更新方法并設置一下 [ValidateInput(false)] 標識才可以。

[ValidateInput(false)]
public override ActionResult Insert(InformationInfo info)
{
	info.Editor = CurrentUser.Name;
	info.EditTime = DateTime.Now;

	return base.Insert(info);
}

[ValidateInput(false)]
public override ActionResult Update(string id, FormCollection formValues)
{
	return base.Update(id, formValues);
}

如通知公告的內(nèi)容編輯界面如下所示。

基于MVC4+EasyUI的Web開發(fā)框架形成之旅--基類控制器CRUD的操作

3、基類的獲取對象數(shù)據(jù)方法

我們在很多接口里面,都要求獲取單一對象的數(shù)據(jù)信息,我在基類接口里面定義了一個FindByID方法,就是從業(yè)務對象里面,根據(jù)主鍵ID信息,獲取一個對象的數(shù)據(jù),把他轉(zhuǎn)換為Json傳遞到View視圖里面使用即可。

/// <summary>
/// 查詢數(shù)據(jù)庫,檢查是否存在指定ID的對象
/// </summary>
/// <param name="id">對象的ID值</param>
/// <returns>存在則返回指定的對象,否則返回Null</returns>
public virtual ActionResult FindByID(string id)
{
	ActionResult result = Content("");
	T info = baseBLL.FindByID(id);
	if (info != null)
	{
		result = JsonDate(info);
	}

	return result;
}

其中的JsonDate方法是為了避免日期類型的數(shù)值在序列化中出現(xiàn)錯誤格式,包裝的一個方法,如下所示。

/// <summary>
/// 返回處理過的時間的Json字符串
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public ContentResult JsonDate(object date)
{
	var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
	return Content(JsonConvert.SerializeObject(date, Formatting.Indented, timeConverter));
}

在View視圖里面使用控制器方法,綁定數(shù)據(jù)到查看界面里面的代碼如下所示。

//綁定查看詳細信息的方法
function BindViewInfo() {
	var ID = $("#grid").datagrid('getSelections')[0].ID;            
	//發(fā)送請求
	$.getJSON("/Information/FindByID?r=" + Math.random() + "&id=" + ID, function (info) {
		$("#ID2").val(info.ID);
		$("#Title2").text(info.Title);
		$("#Content2").html(info.Content);
		$("#Attachment_GUID2").text(info.Attachment_GUID);
		$("#Editor2").text(info.Editor);
		$("#EditTime2").text(info.EditTime);

		ShowUpFiles(info.Attachment_GUID, 'divViewAttach');
	});
}

具體效果如下所示:

基于MVC4+EasyUI的Web開發(fā)框架形成之旅--基類控制器CRUD的操作

4、基類刪除操作方法

在GridView里面,我們提供了刪除數(shù)據(jù)的按鈕,具體視圖里面使用的代碼如下所示。

//然后確認發(fā)送異步請求的信息到后臺刪除數(shù)據(jù)
$.messager.confirm("刪除確認", "您確認刪除選定的記錄嗎?", function (deleteAction) {
	if (deleteAction) {
		$.get("/Information/DeletebyIds", postData, function (data) {
			if (data == "true") {
				$.messager.alert("提示", "刪除選定的記錄成功");
				$("#grid").datagrid("reload");
			}
			else {
				$.messager.alert("提示", data);
			}
		});
	}
});

后臺控制器的基類刪除方法如下所示。

/// <summary>
/// 刪除多個ID的記錄
/// </summary>
/// <param name="ids">多個id組合,逗號分開(1,2,3,4,5)</param>
/// <returns></returns>
public virtual ActionResult DeleteByIds(string ids)
{bool result = false;
	if (!string.IsNullOrEmpty(ids))
	{
		string[] idArray = ids.Split(new char[] { ',' });
		foreach (string strId in idArray)
		{
			if (!string.IsNullOrEmpty(strId))
			{
				baseBLL.Delete(strId);
			}
		}
		result = true;
	}
	return Content(result);
}

以上就是基類控制器增刪改查的一些通用方法的封裝,業(yè)務對象控制器類,如果有特殊的需要,可以對方法進行重寫即可,非常方便使用,從而減少了很多重復編寫的代碼,并可以使得頁面的操作統(tǒng)一化,提高生產(chǎn)效率。


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI