目錄
1. 介紹
2. 軟件環境
4. jqGrid和AJAX
5. GridSettings
8. 數據實體類和LINQ
“MVC網站教程”系列的目的是教你如何使用 ASP.NET MVC 創建一個基本的、可擴展的網站。
3) MVC網站教程(三):動態布局和站點管理(涉及技術:AJAX、jqGrid、Controller擴展、HTML Helpers等等)
4) MVC網站教程(四):MVC4網站中集成jqGrid表格插件(涉及技術:AJAX,JSON,jQuery,LINQ和序列化)
系列的第一篇文章“多語言網站框架”, 主要講解如何去創建一個支持多語言的MVC網站,同時也講解了用戶認證和注冊機制的實現。使用了微軟的Entity Framework框架和LINQ查詢技術。
系列的第二篇文章“異常管理”,提出了詳細的異常管理規則並在ASP.NET MVC網站中實現異常管理,還提供一些通用的日志記錄和異常管理的源代碼。這些源代碼不僅可以在任何ASP.NET網站中被重用(或經過比較小的改動適用),而且可以重用到任何.NET項目中。
系列的第三篇文章“動態布局和站點管理”,通過AJAX,jqGrid,自定義操作結果,控制器擴展,HTML幫助器和一些通用的C#源代碼和JavaScript腳本實現了站點動態布局和站點管理,這些功能支持擴展和重用到其他項目中。
系列的第四篇(即本文),將詳細介紹使用AJAX,JSON,jQuery,LINQ和序列化技術將jqGrid表格插件集成到MVC4網站中。
“MVC網站教程”系列的示例網站是采用增量式和迭代式軟件過程開發的,這意味着系列中每一篇博文會在前一篇的解決方案中添加更多的功能,所以本文提供的示例下載只包含系列目前為止所介紹的功能。
本博文的第一部分介紹構件塊的使用,第二部分介紹將jqGrid表格插件集成到MVC基礎站點解決方案的步驟,使用到技術有AJAX,JSON,JavaScript和第一部分介紹的構件塊。
1. .NET 4.0 Framework
2. Visual Studio 2010 (or Express edition)
3. ASP.NET MVC 4.0
4. SQL Server 2008 R2 (or Express Edition version 10.50.2500.0)
在運行示例代碼之前,你應該做下面事情:
1. 首先使用“管理員身份”運行CreateEventLogEntry控制台項目程序產生的exe,用來在事件日志中創建“MVC Basic”事件源。(EventLog在寫日志時會創建指定名稱的類別默認為“應用程序”的事件源。但是ASP.NET網站沒有足夠的權限來創建事件源,需要本地桌面應用程序)
2. 在你的SQL Server服務器中創建一個名為MvcBasicSite的數據庫,然后用我提供的MvcBasicSiteDatabase.bak文件進行數據庫還原。
3. 修改MVC應用程序示例的Web.config配置文件中的鏈接字符串。
示例帳號
1) 管理員帳戶:Administrator 密碼:tm77dac
2) 普通帳戶: Ana 密碼:ana
本博文示例下載:
1) MVC4網站中集成jqGrid表格插件-示例源代碼.zip
2) MVC4網站中集成jqGrid表格插件-數據庫.zip
jqGrid是一個支持AJAX的開源的javascript控件,它提供在網頁上顯示和操作表格數據,並且支持通過AJAX回調函數動態的加載數據。
關於jqGrid控件的:
幫助文檔詳細請看:http://www.trirand.com
示例詳細請看:http://www.trirand.com/blog/jqgrid/jqgrid.html
下面jqGrid插件包中重要的組件必須集成到網站應用程序中:
1) jquery.jqGrid.min.js:壓縮格式的jqGrid表格插件腳本庫。
2) jquery.jqGrid.src.js:jqGrid表格插件腳本庫源碼。
3) ui.jqgrid.css:jqGrid表格插件的css樣式文件。
4) 一些命名為grid.local-XX.js特定語言文件。這里的XX是語言的兩字符代碼。
除了上面這些重要組件,我們還會在http://jqueryui.com/themeroller/下載一個或多個jQuery UI定制化主題。在當前解決方案中我使用的是Redmond(微軟)定制版本的主題。
AJAX是異步的JavaScript和XML的縮寫。AJAX不是單一的技術,而是一組相互關聯用於創建異步web應用程序的開發技術。使用AJAX技術,web應用程序能異步發送數據和異步接收數據,異步方式不會影響當前頁的顯示和操作並且通過AJAX技術還能避免整個頁面的刷新。
在下面圖中,我使用UML圖展示了“傳統Web系統模型”和“AJAX Web系統模型”。
從“傳統web系統模型”圖中可知,每個用戶界面端(eg:瀏覽器)的用戶請求都會向web應用程序端(運行在web服務器)直接發送一個HTTP請求,在Web應用程序處理請求后響應一個HTML頁面(HTTP+CSS)到瀏覽器,最后在瀏覽器中呈現。
MVC基礎網站是基於AJAX的Web應用程序,當瀏覽器端發出一個用戶請求,用戶界面組件會觸發一個JavaScript調用到AJAX Engine組件。這個引擎負責渲染用戶界面和與服務端進行通信。AJAX技術允許用戶與應用程序發生異步的交互---與服務器進行獨立的通信。注意AJAX引擎給Web應用程序發送一個HTTP請求並且僅接收需要的數據(而不是整個HTML頁面)。
這個主要類是用來存儲jqGrid的設置信息並進行分頁和排序。
如你在上面類圖所見,這個類包含4個屬性用於存儲當前grid設置信息。
1) PageIndex:存儲當前頁索引(1表示第一頁……);
2) PageSize:存儲頁尺寸(設置一個grid頁面能加載的最大行數);
3) SortColumn:存儲排序的列;
4) SortOrder:存儲排序順序(ASC或DESC);
這個類實現了Serializable接口,重寫了ToString()方法將當前grid設置信息轉化為string,並且提供了第二個構造函數用於從序列化數據創建一個新的GridSettings類實例。
下面源代碼展示了本類的主要方法,用於使用當前grid設置信息以及從給定的數據源中加載數據。注意,這個數據源參數是使用LINQ創建的IQueryable查詢。
public IQueryable<T> LoadGridData<T>(IQueryable<T> dataSource, out int count)
{
var query = dataSource;
//
// Sorting and Paging by using the current grid settings.
//
query = query.OrderBy<T>(this.SortColumn, this.SortOrder);
count = query.Count();
//
if (this.PageIndex < 1)
this.PageIndex = 1;
//
var data = query.Skip((this.PageIndex - 1) * this.PageSize).Take(this.PageSize);
return data;
}
從上面代碼可知,LoadGridData是一個泛型方法,所以它能用於加載任何類型的數據並且通過out參數返回結果計數。首先使用grid設置信息將數據進行排序,然后計算數據源計數,最后僅從數據庫中加載所需頁面的數據並返回。
注意GridSettings類通過使用ModelBinder特性與GridModelBinder類進行關聯。
ASP.NET MVC模型綁定通過引入一個抽象層簡化了控制器操作,這個抽象層記錄屬性的隱射,與ASP.NET請求數據協作一起完成自動填充控制器操作參數以及類型轉換。
GridModelBinder是我自定義的綁定模型,作用於GridSettings類,使用jqGrid參數來綁定其屬性。
如上面類圖所見,這個類只有一個命名為BindModel的方法,並且用於實現IModelBinder接口。
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
try
{
var request = controllerContext.HttpContext.Request;
return new GridSettings
{
PageIndex = int.Parse(request["page"] ?? "1"),
PageSize = int.Parse(request["rows"] ?? "20"),
SortColumn = request["sidx"] ?? "",
SortOrder = request["sord"] ?? "asc",
};
}
catch
{
//
// For unexpected errors use the default settings!
//
return null;
}
}
從上面源代碼中可知,HTTP請求中的參數來自於jqGrid插件,通過JavaScript調用用於創建和初始化一個新的GridSettings對象,該對象用於做為控制器的模型。
這個類擴展了LINQ,用於簡化排序過程。通過上述GridSettings類中的SortColumn和SortOrder屬性。
如上面類圖中可知,這個類只有一個靜態的、命名為OrderBy的泛型方法。
public static IQueryable<T> OrderBy<T>(
this IQueryable<T> query, string sortColumn, string direction)
{
string methodName = string.Format("OrderBy{0}",
direction.ToLower() == "asc" ? "" : "descending");
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
//
foreach (var property in sortColumn.Split('.'))
{
memberAccess = MemberExpression.Property(memberAccess ?? (parameter as Expression), property);
}
//
LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter);
MethodCallExpression result = Expression.Call(
typeof(Queryable),
methodName,
new[] { query.ElementType, memberAccess.Type },
query.Expression,
Expression.Quote(orderByLambda));
//
// For the sortColumn=='User.Username' and direction=="desc" ==>
// "OrderByDescending(p => p.User.Username)" expression
// will be appended to the input query!
//
return query.Provider.CreateQuery<T>(result);
}
上面代碼,根據指定的排序列和排序方向創建了一個lambda表達式,然后將結果附加到指定的輸入查詢中。注意排序列可能是簡單的像“ID”也可能是復雜的像“User.UserName(在數據實體之間使用導航屬性)”
用於本例的數據實體類命名為VisitorLog(置於Logic項目中),並且它包含了一系列方法用於從VisitorLogs數據庫表中訪問數據。
這個類的主要方法是用於讀取訪問日志數據並且最終使用jqGrid表格插件顯示給用戶。
public static IQueryable<VisitorLog> SearchLogByDates(MvcBasicSiteEntities dataContext, DateTime searchStartDate, DateTime searchEndDate)
{
if (searchStartDate.Date == DateTime.MinValue && searchEndDate.Date == DateTime.MinValue)
{
return dataContext.VisitorLogs.AsQueryable();
}
else if (searchStartDate.Date == DateTime.MinValue)
{
var searchResults = dataContext.VisitorLogs.Where(c =>
EntityFunctions.TruncateTime(c.StartDate) <= EntityFunctions.TruncateTime(searchEndDate));
//
return searchResults.AsQueryable();
}
else if (searchEndDate.Date == DateTime.MinValue)
{
var searchResults = dataContext.VisitorLogs.Where(c =>
EntityFunctions.TruncateTime(c.StartDate) >= EntityFunctions.TruncateTime(searchStartDate));
//
return searchResults.AsQueryable();
}
else
{
var searchResults = dataContext.VisitorLogs.Where(c =>
EntityFunctions.TruncateTime(c.StartDate) >= EntityFunctions.TruncateTime(searchStartDate) &&
EntityFunctions.TruncateTime(c.StartDate) <= EntityFunctions.TruncateTime(searchEndDate));
//
return searchResults.AsQueryable();
}
}
如上面源代碼所示,這個方法根據給定的參數構建了4種可能的LINQ表達式:
1) 查詢給定日期時間間隔內的所有實體,當日期參數都是不等於DateTime.MinValue的有效值時。
2) 查詢所有實體,當日期參數都是無效值時。
3) 查詢指定開始日期到今天內的所有實體,當只有開始日期是有效值時。
4) 查詢截至到給定結束日期內的所有實體,當只有結束日期是有效值時。
所有前文提到的構件塊都是用於將jqGrid表格插件集成到MVC解決方案中的。為了查看集成后的結果,你必須打開管理區域的“Visitors”頁面。(管理員帳號:Administrator,密碼:tm77dac)
從上面截圖中可知,這個grid表格擁有5個不同類型的列(字符串、日期時間、布爾值),並且所有列都支持排序。最后一列命名為“Actions”使用了我的ImageButton自定義HTML幫助器。當用戶按下“Delete”圖片按鈕時,與之關聯的訪問日志條目將從數據庫中刪除。
在grid表格的底部有一個分頁控制器,包括:當前頁數,導航按鈕,每一頁顯示的結果數。通過使用這些導航控件用戶能瀏覽任意他想要的數據。
在grid表格的底部還有兩個操作按鈕:“Reload Grid”按鈕(圖片按鈕)和“Delete All”按鈕。
注意這個頁面,通過使用國際化和本地化被實現為支持三種語言:English, Romanian (Română), German (Deutch),並且能擴展支持其他語言。同樣這個頁面的message和控制器(labels,buttons,tool tips等等)都支持多語言。
將jqGrid表格插件集成到MVC解決方案只需要下面四個步驟:
一、部分視圖
在前面創建的構件塊基礎上,集成jqGrid表格插件的第一步是創建一個命名為_VisitorLogGrid.cshtml部分視圖,這個視圖是grid表格和分頁控制的容器。
<table id="_visitorLogGrid" cellpadding="0" cellspacing="0"> </table> <div id="_visitorLogPager" style="text-align: center;"> </div>
在上面HTML代碼中定義的兩個ID屬性非常重要,因為它們將被用於下一步。
二、JavaScript
第二步是創建一個命名為VisitorLogGrid.js的腳本文件,並且放入Script文件夾中。
function showGrid() {
$('#_visitorLogGrid').jqGrid({
caption: paramFromView.Caption,
colNames: ['ID', paramFromView.VisitorName, paramFromView.StartDate,
paramFromView.EndDate, paramFromView.WasTimeOut, paramFromView.Actions],
colModel: [
{ name: 'ID', width: 1, hidden: true, key: true },
{ name: 'VisitorName', index: 'User.Username', width: 300 },
{ name: 'StartDate', index: 'StartDate', width: 150 },
{ name: 'EndDate', index: 'EndDate', width: 150 },
{ name: 'WasTimeOut', index: 'WasTimeOut', width: 120,
formatter: "checkbox", align: "center" },
{ name: 'Action', index: 'ID', width: 70, align: "center" }
],
hidegrid: false,
pager: jQuery('#_visitorLogPager'),
sortname: 'ID',
rowNum: paramFromView.PageSize,
rowList: [10, 20, 50, 100],
sortorder: "desc",
width: paramFromView.Width,
height: paramFromView.Height,
datatype: 'json',
caption: paramFromView.Caption,
viewrecords: true,
mtype: 'GET',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
userdata: "userdata"
},
url: paramFromView.Url
}).navGrid('#_visitorLogPager', { view: false, del: false, add: false, edit: false, search: false },
{ width: 400 }, // default settings for edit
{}, // default settings for add
{}, // delete instead that del:false we need this
{}, // search options
{} /* view parameters*/
).navButtonAdd('#_visitorLogPager', {
caption: paramFromView.DeleteAllCaption, buttonimg: "", onClickButton: function () {
if (confirm(paramFromView.DeleteAllConfirmationMessage)) {
document.location = paramFromView.ClearGridUrl;
}
else {
$('#_visitorLogGrid').resetSelection();
}
}, position: "last"
});
};
$(document).ready(function () {
showGrid();
});
從上面JavaScript代碼中可知,這里使用了document.ready事件用於顯示表格當document加載完畢時。還有另一個主要的函數命名為showGrid,它定義了jqGrid表格的列、屬性、分頁和導航按鈕。
注意在grid表格的標題、列、按鈕和消息中使用的所有標簽文本值都來自於資源文件(,以實現多語系),通過parameFormView對象進行傳遞。
這里有一些非常重要的細節,需要強調下:
1) _visitorLogGrid字符串是一個Id屬性,在第一步的部分視圖中定義並且用於創建grid表格。
2) _visitorLogPager字符串是一個Id屬性,在第一步的部分視圖中定義並且用於創建grid表格的分頁控制和導航按鈕(“Refresh”和“Delete All”)。
3) colNames屬性用於定義grid表格中的所有列名(包括隱藏列)。
4) colModel屬性用於定義列行為和與數據實體屬性綁定的排序索引。
5) rowNum屬性用於設置grid表格當前頁尺寸(每頁包含的行數),通過paramFromView對象的PageSize屬性為其賦值。
6) width屬性用於設置grid表格的寬度像素,通過paramFromView對象的Width屬性為其賦值。
7) height屬性用於設置grid表格的高度像素,通過paramFromView對象的Height屬性為其賦值。
8) url設置一個URL鏈接,jqGrid通過AJAX技術使用該鏈接在服務器中獲取數據,通過paramFromView對象的Url屬性為其賦值。
9) Delete All按鈕使用paramFromView對象的ClearGridUrl屬性設置一個Url鏈接,用於執行“Delete All”操作。
10) JsonReader屬性定義了從服務器中讀取的JSON數據的鍵值對名字。
三、Razor視圖
第三步是創建主頁面,它將使用第二步中創建的JavaScript文件。這個頁面是位於View\VisitorsLog文件夾下的Index.cshtml視圖。
@using MvcBasicSite.Models.Grid;
@{
ViewBag.Title = Resources.Resource.VisitorLogIndexTitle;
Layout = "~/Views/Shared/_AdminLayout.cshtml";
//
int pageSize = 20;
if (Session["VisitorLogGridSettings"] != null)
{
//
// Get from cache the last page zise selected by the user.
//
GridSettings grid = new GridSettings((string)Session["VisitorLogGridSettings"]);
pageSize = grid.PageSize;
}
//
// Restore the last search params from cache.
//
string startDate = (Session["StartDate"] == null
? string.Empty
: ((DateTime)Session["StartDate"]).ToShortDateString());
string endDate = (Session["EndDate"] == null
? string.Empty
: ((DateTime)Session["EndDate"]).ToShortDateString());
}
<table>
<tr>
<td style="text-align: right; margin-top: 0px;">
@using (Ajax.BeginForm("Search", "VisitorLog",
new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "jqGrid",
OnSuccess = "showGrid()"
}))
{
<table>
<tr>
<td>
<label>@Resources.Resource.VisitorLogIndexFrom</label>
<input type="text" id="from" name="from"
data-datepicker="true" value="@startDate" />
</td>
<td>
<label>@Resources.Resource.VisitorLogIndexTo</label>
<input type="text" id="to" name="to"
data-datepicker="true" value="@endDate" />
</td>
<td style="text-align: right; margin-top: 0px;">
<input type="submit" name="_search"
value="@Resources.Resource.VisitorLogApplyFilter"
class="searchButton" />
</td>
</tr>
</table>
}
</td>
</tr>
</table>
<div id="jqGrid">
@Html.Partial("_VisitorLogGrid")
</div>
<script type="text/javascript">
var paramFromView = {
DeleteAllCaption: '@Resources.Resource.VisitorLogDeleteAllCaption',
ClearGridUrl: '@Url.Content("~/VisitorLog/ClearGridData")',
DeleteAllConfirmationMessage: '@Resources.Resource.VisitorLogDeleteAllDataConfirmation',
Url: '@Url.Content("~/VisitorLog/GetData")',
Width: 790,
Height: 464,
Caption: '@Resources.Resource.VisitorLogIndexTitle',
VisitorName: '@Resources.Resource.VisitorLogIndexVisitorName',
StartDate: '@Resources.Resource.VisitorLogIndexStartDate',
EndDate: '@Resources.Resource.VisitorLogIndexEndDate',
WasTimeOut: '@Resources.Resource.VisitorLogIndexWasTimeOut',
Actions: '@Resources.Resource.VisitorLogIndexActions',
PageSize: @pageSize
}
</script>
@section scripts
{
@Content.Script("VisitorLogGrid.js", Url)
}
在上面razor視圖的第一部分中,我設置了頁面Title和Layout,並且從HTTP會話中獲取最后一次設置的GridSettings對象和查詢參數(開始日期和結束日期)用於當前頁。
然后,使用一個table通過設置開始日期和結束日期過濾結果集。注意,這個AJAX表單使用VisitorLog控制器的Search操作僅僅獲取需要的數據,在操作成功時調用javascript的showGrid函數,並且只有頁面中包含grid表格的部分視圖被更新。
在這一步中,呈現grid表格的部分視圖和JavaScript腳本代碼通過使用Razor塊:@Html.Partial("_VisitorLogGrid") 和 @Content.Script("VisitorLogGrid.js", Url) 引入。
在視圖的最后一部分,是一塊內聯的JavaScript腳本代碼,它創建並且初始化一個paramFromView對象,該對象用於第二步中的javaScript腳本代碼。通過這種方式,與最后一次GridSettings對象動態通信並且所有的標簽值、按鈕文本和消息信息都是從資源文件中讀取(基於當前選擇的語言)。注意下面兩個URL鏈接設置,關聯了對應的控制器操作。
1) VisitorLog/GetData:獲取grid表格數據。
2) VisitorLog/ClearGridData:清除滿足當前過濾設置的所有匹配數據。
四、控制器
現在來查看VisitorLogController控制器類,分析實現第三步中視圖使用到的操作。
jqGrid表格使用AJAX加載數據所調用的主要方法如下:
public JsonResult GetData(GridSettings grid)
{
if (_fromIndex && Session["VisitorLogGridSettings"] != null)
{
//
// Get grid settings from cache!
//
grid = new GridSettings((str ing)Session["VisitorLogGridSettings"]);
}
//
_fromIndex = false; // Must be set on false here!
//
// Load the data from the database for the current grid settings.
//
DateTime searchStartDate = (Session["StartDate"] == null ?
DateTime.MinValue : (DateTime)Session["StartDate"]);
DateTime searchEndDate = (Session["EndDate"] == null ?
DateTime.MinValue : (DateTime)Session["EndDate"]);
int count;
var query = grid.LoadGridData<VisitorLog>(
VisitorLog.SearchLogByDates(_db, searchStartDate, searchEndDate), out count);
var data = query.ToArray();
//
// Convert the results in JSON jqGrid format.
//
string gridSettingsString = grid.ToString(); // Used to preserve grid settings!
Session["VisitorLogGridSettings"] = gridSettingsString;
gridSettingsString = null;
var result = new
{
total = (int)Math.Ceiling((double)count / grid.PageSize),
page = grid.PageIndex,
records = count,
rows = (from host in data
select new
{
ID = host.ID,
VisitorName = GetVisitorNameForBinding(host),
StartDate = host.StartDate.ToString(),
EndDate = host.EndDate.ToString(),
WasTimeOut = (host.WasTimeOut ?? false),
Action = string.Format("{0}",
RenderHelpers.ImageButton(
this,
Resources.Resource.DeleteTip,
"~/Content/Images/Delete.gif",
"Delete",
new { id = host.ID },
new { style = "border:0px;" }))
}).ToArray()
};
//
// Convert to JsonResult before to return.
//
return Json(result, JsonRequestBehavior.AllowGet);
}
在上面代碼中,你能看到GridSettings對象,這個對象做為方法參數通過我們自定義的GridModelBinder機制使用頁面上用戶的設置進行賦值,用於分頁和排序。然后這個參數對象或者是從緩存數據中創建的GridSettings對象(當從別的頁面返回該頁時,從緩存中取)用於根據當前過濾設置加載數據並且用於為當前頁面創建行數據。最后結果數據被轉化為JSON格式並返回。
JSON或JavaScript對象表示法,是設計為基於文本的數據交換開放標准協議。它來源於JavaScript腳本語言為了提供簡單的數據結構和關聯數組,但又是一個完全獨立於語言的文本格式。
注意,上面代碼中創建了一個命名為result的JSON對象,它擁有四個屬性(total,page,records和rows)與在第二步的JavaScript代碼中定義的命名相同。rows屬性包含了用於grid表格當前頁的行數據,並且JSON對象中的每一行所包含的屬性必須在第二步中jqGrid表格的colModel屬性中定義。
在下面截圖中,你能看到Visitors(Index)頁面,當用戶指定開始日期和結束日期(通過data picker時間控件)觸發控制器操作返回過濾后的結果集。
當用戶按下“Apply Filter”按鈕后,將會通過AJAX方式調用下面方法,根據用戶指定的開始日期和結束日期查詢訪問日志。
public PartialViewResult Search()
{
string startDate = Request["from"];
string endDate = Request["to"];
//
// Cache the start and end dates into the session to be used by later one in the view.
//
Session["StartDate"] = (startDate.Length < 1 ? null :
(object)DateTime.Parse(startDate, Thread.CurrentThread.CurrentCulture));
Session["EndDate"] = (endDate.Length < 1 ? null :
(object)DateTime.Parse(endDate, Thread.CurrentThread.CurrentCulture));
//
return PartialView("_VisitorLogGrid");
}
上面代碼,從request對象中獲取參數,然后將其值緩存到session會話中待返回到視圖中使用,並且最后將_VisitorLogGrid部分試圖呈現給用戶。
用戶調用的第三個方法,根據當前過濾條件刪除訪問日志。
public ActionResult ClearGridData()
{
DateTime searchStartDate = (Session["StartDate"] == null ?
DateTime.MinValue : (DateTime)Session["StartDate"]);
DateTime searchEndDate = (Session["EndDate"] == null ?
DateTime.MinValue : (DateTime)Session["EndDate"]);
VisitorLog.DeleteLogByDates(_db, searchStartDate, searchEndDate);
//
return RedirectToAction("Index");
}
上面代碼,使用當前session會話中緩存的開始日期和結束日期參數刪除數據庫中匹配返回數據,然后重定向到Index頁面。
通過以上四步,即可將jqGrid插件引入到MVC項目中,趕緊試試吧……
終於把這個小系列翻譯完了,覺得還不錯的,多幫推薦推薦……
原文:http://www.codeproject.com/Articles/594150/MVC-Basic-Site-Step-jqGrid-In
作者:Raul Iloc






