中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

基于MVC4+EasyUI的Web開發框架形成之旅--MVC控制器的設計

發布時間:2020-07-16 10:07:52 來源:網絡 閱讀:271 作者:wuhuacong 欄目:開發技術

自從上篇《基于MVC4+EasyUI的Web開發框架形成之旅--總體介紹》總體性的概括,得到很多同行的關注和支持,不過上一篇主要是介紹一個總體的界面效果和思路,本系列的文章將逐步介紹其中的細節,本文主要介紹整個Web開發框架中的MVC控制器的設計。在設計之初,我就希望盡可能的減少代碼,提高編程模型的統一性。因此希望能夠以基類繼承的方式,和我Winform開發框架一樣,盡可能通過基類,而不是子類的重復代碼來實現各種通用的操作。

1、登錄控制的控制器基類設計

我們知道,一般我們創建一個MVC的控制器,都是基于Controller這樣的基類來實現。如下代碼所示。

基于MVC4+EasyUI的Web開發框架形成之旅--MVC控制器的設計

public class TestController : Controller
{
	//
	// GET: /Test/

	public ActionResult Index()
	{
		return View();
	}

}

在我的Winform開發框架里面,用到了泛型的類型,非常方便實現業務邏輯和數據訪問基類的設計,控制器是否也可以這樣做的呢?

我們知道,一般的MVC控制器需要驗證用戶是否已經登陸了,這也是很多常見Web操作前的驗證,還有對異常的處理,在MVC的基類,可以一并進行記錄(這個非常不錯),于是我們先來設計一個驗證用戶身份是否登陸的基類BaseController

/// <summary>
/// 所有需要進行登錄控制的控制器基類
/// </summary>
public class BaseController : Controller 
{
	/// <summary>
	/// 當前登錄的用戶屬性
	/// </summary>
	public UserInfo CurrentUserInfo { get; set; }

	/// <summary>
	/// 重新基類在Action執行之前的事情
	/// </summary>
	/// <param name="filterContext">重寫方法的參數</param>
	protected override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		base.OnActionExecuting(filterContext);
		//得到用戶登錄的信息
		CurrentUserInfo = Session["UserInfo"] as UserInfo;

		//判斷用戶是否為空
		if (CurrentUserInfo == null)
		{
			Response.Redirect("/Login/Index");
		}
	}

	protected override void OnException(ExceptionContext filterContext)
	{
		base.OnException(filterContext);

		//錯誤記錄
		WHC.Framework.Commons.LogTextHelper.Error(filterContext.Exception);

		// 當自定義顯示錯誤 mode = On,顯示友好錯誤頁面
		if (filterContext.HttpContext.IsCustomErrorEnabled)
		{
			filterContext.ExceptionHandled = true;
			this.View("Error").ExecuteResult(this.ControllerContext);
		}
	}
........................
}

有了這個基類,我們在主頁的Home控制類,就可以使用用戶信息對象了進行操作了,而且必須要求客戶登陸了。

public class HomeController : BaseController
{
	public ActionResult Index()
	{
		if (CurrentUserInfo != null)
		{
			ViewBag.FullName = CurrentUserInfo.FullName;
			ViewBag.Name = CurrentUserInfo.Name;
		}
		return View();
	}
................
}

 

2、數據訪問業務基類控制器的設計

我在我的Winform開發框架里面,對很多基類都使用泛型進行設計,這樣可以傳遞相應的數據類型到基類里面進行處理,如下面的BLL層的業務對象定義代碼如下所示。

namespace WHC.Security.BLL
{
    /// <summary>
    /// 角色信息業務管理類
    /// </summary>
    public class Role : BaseBLL<RoleInfo>
    {

....................
/// <summary>
/// 業務基類對象
/// </summary>
/// <typeparam name="T">業務對象類型</typeparam>
public class BaseBLL<T> where T : BaseEntity, new()
{

	/// <summary>
	/// 插入指定對象到數據庫中
	/// </summary>
	/// <param name="obj">指定的對象</param>
	/// <returns>執行操作是否成功。</returns>
	public virtual bool Insert(T obj)
	{
		return baseDal.Insert(obj);
	}

............

業務對象Role,要求傳入RoleInfo給基類處理,這樣基類就能定義到都對應的T為具體的RoleInfo類型了。在MVC的控制器是否也可以這樣做呢?當然可以,下面是我定義的一個控制器繼承關系圖。

基于MVC4+EasyUI的Web開發框架形成之旅--MVC控制器的設計

上面的介紹也已經比較明白了,其實就是在BusinessController<B, T>里面傳入了兩個參數,定義代碼如下所示。

/// <summary>
/// 本控制器基類專門為訪問數據業務對象而設的基類
/// </summary>
/// <typeparam name="B">業務對象類型</typeparam>
/// <typeparam name="T">實體類類型</typeparam>
public class BusinessController<B, T> : BaseController
	where B : class
	where T : WHC.Framework.ControlUtil.BaseEntity, new()
{

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

................

我根據傳入的BLL業務對象類型B,對象實體類類型T,那么我們就可以構造對應的baseBLL對象,然后調用其基類接口實現基本的操作,如插入,刪除,更新,查找等等,這樣的模式就和我的Winform開發框架的理念非常吻合了。

我們以角色控制器來說明,它的定義如下所示,如果不需要實現額外的接口(除了常見的操作),基本上不需要寫任何代碼了,因為所有很多常見的操作,都已經封裝在了基類控制器BusinessController<B, T>里面了。

/// <summary>
/// 角色業務操作控制器
/// </summary>
public class RoleController : BusinessController<Role, RoleInfo>
{
	public RoleController() : base()
	{
	}

...............

對于一些需要特殊數據處理的操作,可以增加一些自定義的接口函數,也可以重寫基類的一些接口,實現數據的相應處理。如我的菜單界面顯示中,需要根據縮進的層級對菜單名稱進行縮進,以便更好的展示它們的層級結構,那么我就需要對分頁函數進行重寫了,如下代碼所示是整個菜單Menu類的控制器類代碼。

public class MenuController : BusinessController<Menu, MenuInfo>
{
	public override ActionResult FindWithPager()
	{
		string where = GetPagerCondition(); //基類實現
		PagerInfo pagerInfo = GetPagerInfo(); //基類實現            
		List<MenuInfo> list = baseBLL.FindWithPager(where, pagerInfo);
		list = CollectionHelper<MenuInfo>.Fill("-1", 0, list, "PID", "ID", "Name");

		//Json格式的要求{total:22,rows:{}}
		//構造成Json的格式傳遞
		var result = new { total = pagerInfo.RecordCount, rows = list };
		return JsonDate(result);
	}

	/// <summary>
	/// 用作下拉列表的菜單Json數據
	/// </summary>
	/// <returns></returns>
	public ActionResult GetDictJson()
	{
		List<MenuInfo> list = baseBLL.GetAll();
		list = CollectionHelper<MenuInfo>.Fill("-1", 0, list, "PID", "ID", "Name");

		List<CListItem> itemList = new List<CListItem>();
		foreach (MenuInfo info in list)
		{
			itemList.Add(new CListItem(info.Name, info.ID));
		}
		return Json(itemList, JsonRequestBehavior.AllowGet);
	}
}

 

我們來看看一段HTML頁面里面,使用javascript腳本調用控制器API來實現數據的綁定的操作,也就是使用示例。

$.getJSON("/Role/FindById?r=" + Math.random() + "&id=" + id, function (json) {
	$("#txtID").val(json.ID);
	$("#txtName").val(json.Name);
	$("#txtNote").val(json.Note);
});

上面這個很標準的接口FindById是業務基類控制器BusinessController<B, T>里提供的。

當然,BusinessController里面可以類似我Winform開發框架里面基類一樣,提供很豐富的操作接口,如返回列表Json集合,增刪改查的操作及返回,分頁數據的返回,以及一些特殊的操作都可以實現。而這些都不需要子類進行任何實現。

如下面實際案例的用戶登陸日志,里面的界面功能還是很豐富的,當他的控制器業務類不需要任何實現,只需要繼承基類即可。

基于MVC4+EasyUI的Web開發框架形成之旅--MVC控制器的設計

    public class LoginLogController : BusinessController<LoginLog, LoginLogInfo>
    {
        public LoginLogController() : base()
        {
        }

    }

界面部分代碼如下所示。

//實現對DataGird控件的綁定操作
function InitGrid(queryData) {
	$('#grid').datagrid({   //定位到Table標簽,Table標簽的ID是grid
		url: '/LoginLog/FindWithPager',   //指向后臺的Action來獲取當前用戶的信息的Json格式的數據
		title: '用戶登陸日志', 
		//下面的這些屬性如果誰不太清楚的話我建議去官方網站去學習
		iconCls: 'icon-view',
		height: 450,
		nowrap: true,
		autoRowHeight: false,
		striped: true,
		collapsible: true,
		pagination: true,
		rownumbers: true,
		//sortName: 'ID',    //根據某個字段給easyUI排序
		sortOrder: 'asc',
		remoteSort: false,
		idField: 'ID',
		queryParams: queryData,  //異步查詢的參數
		columns: [[
			{ field: 'ck', checkbox: true },   //選擇
			{ title: 'ID', field: 'ID', width: 40, sortable: true },  //主鍵
			 { title: '登錄用戶ID', field: 'User_ID', width: 80, sortable: true },
			 { title: '登錄名稱', field: 'LoginName', width: 80, sortable: true },
			 { title: '真實名稱', field: 'FullName', width: 80, sortable: true },
			 { title: '日志描述', field: 'Note', width: 100, sortable: true },
			 { title: 'IP地址', field: 'IPAddress', width: 100, sortable: true },
			 { title: 'Mac地址', field: 'MacAddress', width: 120, sortable: true },
			 { title: '系統編號', field: 'SystemType_ID', width: 120, sortable: true },
			 { title: '記錄日期', field: 'LastUpdated', width: 120, sortable: true },
		]],
		toolbar: [{
			id: 'btnAdd',
			text: '添加',
			iconCls: 'icon-add',
			handler: function () {                        
				ShowAddDialog();//實現添加記錄的頁面
			}
		}, '-', {
			id: 'btnEdit',
			text: '修改',
			iconCls: 'icon-edit',
			handler: function () {                        
				ShowEditOrViewDialog();//實現修改記錄的方法
			}
		}, '-', {
			id: 'btnDelete',
			text: '刪除',
			iconCls: 'icon-remove',
			handler: function () {                        
				Delete();//實現直接刪除數據的方法
			}
		}, '-', {
			id: 'btnView',
			text: '查看',
			iconCls: 'icon-table',
			handler: function () {                        
				ShowEditOrViewDialog("view");//實現查看記錄詳細信息的方法
			}
		}, '-', {
			id: 'btnReload',
			text: '刷新',
			iconCls: 'icon-reload',
			handler: function () {
				//實現刷新欄目中的數據
				$("#grid").datagrid("reload");
			}
		}]
	});

	$('#grid').datagrid({
		onDblClickRow: function (rowIndex, rowData) {
			$('#grid').datagrid('uncheckAll');
			$('#grid').datagrid('checkRow', rowIndex);
			ShowEditOrViewDialog();
		}
	});
}

這個就是我的控制器設計的中心思想了,下一篇繼續介紹整體的MVC系列的Web開發框架,介紹其中Web界面部分的處理和相關經驗,希望大家多多提出寶貴的意見。

向AI問一下細節

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

AI

镇沅| 芒康县| 内乡县| 滨州市| 什邡市| 锦屏县| 屏东市| 宜兰县| 楚雄市| 洪江市| 桑植县| 盘山县| 蓬溪县| 奉贤区| 大化| 田阳县| 榆社县| 玉溪市| 黔南| 齐齐哈尔市| 宜良县| 陵川县| 黄冈市| 黄平县| 卓尼县| 海原县| 镇宁| 呈贡县| 新津县| 麻城市| 阿拉善盟| 卢氏县| 荣成市| 灵寿县| 靖远县| 通渭县| 成都市| 彩票| 宁远县| 金寨县| 石泉县|