【IT168 技术文档】Microsoft Asp.Net MVC3 的Bate version Release有些日子了,园子里关于3所带的新功能、新组件及新方法使用的文章就出了很多,对其好坏我不做评价,但肯定的是,这些文章让我受益匪浅,感受良多。之前做过Asp.Net MVC Version 1的项目,Version1里面的很多功能都比较不完善,但开发出来的效果还是可以令人满意的,特别是在加载速度、代码修改和更新部署上有特别的优势。今天我们将就3的Bate Version所带的WebGrid进行以下两点描述:1.查询条件的绑定,2. WebGrid Sorting Ajax的实现,本文在代码编写上使用的是MVC3新提供的Razor方式(优点:因为它及大的简单了代码的书写;缺点:当前版本没有智能代码提示),可参考Asp.Net MVC3 Razor
一、本文内容
WebGrid的使用
WebGrid Sorting(排序) Ajax的实现
WebGrid Search Conditions(查询条件)的绑定
总结
代码下载 (下载)
二、MVC3 WebGrid 小试
1. WebGrid的使用
WebGrid的使用园子里已经有很多相关的文章了,也不是我们的重点,在这里我们只提供一个示例,为下面代码的描述作比较。
Action:
{
DALDataContext da = new DALDataContext();
var result =da.T_STUDENTs.ToList();
this.ViewData.Model = result;
return View();
}
View:(如果对其中的属性不明白,请参考下面四中的内容
@model List<T_STUDENT>
@{
View.Title = "Gridview";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@{
var grid = new WebGrid(source:Model,
fieldNamePrefix:"grid_",
defaultSort: "StudentName",
canPage:true,
canSort:true,
ajaxUpdateContainerId:"DivGrid",
pageFieldName:"paging",
sortFieldName:"sortField",
rowsPerPage:10);
<div id="DivGrid">
@grid.GetHtml(
columns:grid.Columns(
grid.Column("StudentID", "Student ID"),
grid.Column("StudentName", "Student Name"),
grid.Column("StudentCode", "Student Code"),
grid.Column("Sex", "Sex"),
grid.Column("NRICPassport", "NRIC/Passport No.")
)
)
</div>
<h2>
Page Count:
@Html.Encode(grid.PageCount)
<br/>
Total Record:
@Html.Encode(grid.TotalRowCount)
</h2>
@Html.Encode(grid.FieldNamePrefix)38 }
上面我们就实现了对WebGrid的使用,得到结果如下:
2. WebGrid Sorting(排序) Ajax的实现
我们看,在上面的View代码中黄色背景表示的是创建WebGrid对象实例,其中有这样一行ajaxUpdateContainerId:"DivGrid",他表示的是当WebGrid发生AjaxUpdate事件后,将更新后内容显示到指定的元素中。在我们示例中,我们指定的是一个Div对象。也就是说我们期望得到的结果是,当我们点击标题行的列进行排序后,应该把排序后的新内容放到这个Div中,并且是Ajax操作。但是在实际操作中,浏览器会提示如下信息:

为什么他会提示这样的信息呢?我们点击上面的结果,查看源代码,有如下行:

我们可以看到,他生成的是一个JQuery的操作方式,所以我们必须引用JQuery的类库,如下(本下在_Layout.cshtml中加载的):
<title>@View.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script language="javascript" src="@Url.Content("~/Scripts/jquery-1.4.1.min.js")"></script>
</head>
当你再次运行时,你就会发现,这时他已经是局部刷新了。
3. WebGrid Search Conditions(查询条件)的绑定
我们通常使用Grid的时候肯定不是直接使用的,比如说查询页面,常常有许多查询条件的,我们都知道MVC是没有ViewState的,当我们点击sorting的时候,输入的查询条件就可能会被刷新掉,所以将会影响我们的查询结果,如何解决这个问题呢?
现将View代码修改如下:
@model List<T_STUDENT>
@{
View.Title = "Gridview";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using(Ajax.BeginForm("Gridview","Home",new AjaxOptions{ UpdateTargetId="DivGrid"}) )
{
IDictionary<string, string> searchConditions = new Dictionary<string, string>();
if(TempData["SearchConditions"]!=null)
{
searchConditions = TempData["SearchConditions"] as Dictionary<string, string>;
}
this.TempData["SearchConditions"]=searchConditions;
string studentName = searchConditions.Keys.Contains("StudentName")?searchConditions["StudentName"]:string.Empty;
string nricPassport = searchConditions.Keys.Contains("nricPassport")?searchConditions["nricPassport"]:string.Empty;
<div>
@Html.Encode("Student Name: ")
</div>
@Html.TextBox("StudentName",@studentName)
<div>
@Html.Encode("NRIC/Passport No.: ")
</div>
@Html.TextBox("nricPassport",@nricPassport)
<br/>
<input type="Submit" Text="Search"/>
var grid = new WebGrid(source:Model,
fieldNamePrefix:"grid_",
defaultSort: "StudentName",
canPage:true,
canSort:true,
ajaxUpdateContainerId:"DivGrid",
pageFieldName:"paging",
sortFieldName:"sortField",
rowsPerPage:10);
<div id="DivGrid">
@grid.GetHtml(
columns:grid.Columns(
grid.Column("StudentID", "Student ID"),
grid.Column("StudentName", "Student Name"),
grid.Column("StudentCode", "Student Code"),
grid.Column("Sex", "Sex"),
grid.Column("NRICPassport", "NRIC/Passport No.")
)
)
</div>
<h2>
Page Count:
@Html.Encode(grid.PageCount)
<br/>
Total Record:
@Html.Encode(grid.TotalRowCount)
</h2>
@Html.Encode(grid.FieldNamePrefix)
}
现在我们多了两个查询条件,叫Student Name,NRIC/Password No.,如下图所示:

那么当我们点击Sorting的时候如何它才能保持现有的查询条件不变呢?我所采取的策略是使用TempData保存现有的查询条件,所以我们就需要在Action中获取查询条件并将其放放TempData中,当Action返回时,我们在view中把现有的TempData再次的进行绑定,因为WebGrid的Sorting他请求的是一个URL,而不是提交事件,所以当点击Sorting的时候,他并不会收集form中的对象,但是因为之前的一次查询,我们将查询条件存入了TempData中,所以现在我们可以从TempData中取出查询条件,Action代码修改如下:
{
IDictionary<string, string> searchConditions = new Dictionary<string, string>();
if (this.Request.Form.AllKeys.Length > 0)
{
searchConditions.Add("StudentName", Request["StudentName"]);
searchConditions.Add("nricPassport", Request["nricPassport"]);
}
else
{
object values = null;
if (this.TempData.TryGetValue("SearchConditions", out values))
{
searchConditions = values as Dictionary<string, string>;
}
}
this.TempData["SearchConditions"] = searchConditions;
string studentName = GetSearchConditionValue(searchConditions, "StudentName");
string nric = GetSearchConditionValue(searchConditions, "nricPassport");
DALDataContext da = new DALDataContext();
var result = (from s in da.T_STUDENTs
where (string.IsNullOrEmpty(studentName) || s.StudentName.StartsWith(studentName))
&& (string.IsNullOrEmpty(nric) || s.NRICPassport.StartsWith(nric))
select s).ToList();
this.ViewData.Model = result;
return View();
}
private static string GetSearchConditionValue(IDictionary<string, string> searchConditions, string key)
{
string tempValue = string.Empty;
if (searchConditions != null && searchConditions.Keys.Contains("StudentName"))
{
searchConditions.TryGetValue(key, out tempValue);
}
return tempValue;
}
上在的Action就是实现了这样的一件事情,第一次提交的时候把查询条件给TempData,然后在后面的非Submit事件中,使用已经保存在TempData中的查询条件。这样我们就实现了查询条件与MVC WebGrid的绑定。虽然这样的方案并不是十分的完美,但也是其解决方案之一,如果有那个博友有更好的解决方案,还请拍砖斧正。
上面我们已经讲完了本文主要的3点内容,但是WebGrid中还有一些其它的参数,很多文章都有介绍,在这里我们再多做一次补充,以方便博友阅读此文。
但是通过上文的实例,我们个人觉的他有一些不足,因为他在取Data的时候,一次性的返回所有需要的 Data,然后再将其返回到我们的Action中,这样必然增加了Application与Database之间数据的通信量,如果数据量很大的时候必然也会给网络带来很大的压力,如果我们在Database里就把分页的数据直接返回,那么将大大减少数据传输量(数据库分页也会比较快)。
三、方法及参数说明
WebGrid有两个构造函数,在他的构造函数中所需要的一些参数正是用来指定所创建出来的WebGrid生成的HTML是否具备如分页、排序等功能。主要参数如下:
public WebGrid([Dynamic(new bool[] { false, true })] IEnumerable<object> source, [Optional, DefaultParameterValue(null)] IEnumerable<string> columnNames,
[Optional, DefaultParameterValue(null)] string defaultSort,
[Optional, DefaultParameterValue(10)] int rowsPerPage,
[Optional, DefaultParameterValue(true)] bool canPage,
[Optional, DefaultParameterValue(true)] bool canSort,
[Optional, DefaultParameterValue(null)]
string ajaxUpdateContainerId,
[Optional, DefaultParameterValue(null)]
string fieldNamePrefix,
[Optional, DefaultParameterValue(null)]
string pageFieldName,
[Optional, DefaultParameterValue(null)]
string selectionFieldName,
[Optional, DefaultParameterValue(null)]
string sortFieldName,
[Optional, DefaultParameterValue(null)]
string sortDirectionFieldName);
internal WebGrid(HttpContextBase context, [Dynamic(new bool[] { false, true })] IEnumerable<object> source, [Optional, DefaultParameterValue(null)] IEnumerable<string> columnNames,
[Optional, DefaultParameterValue(null)]
string defaultSort,
[Optional, DefaultParameterValue(10)] int rowsPerPage,
[Optional, DefaultParameterValue(true)] bool canPage,
[Optional, DefaultParameterValue(true)] bool canSort,
[Optional, DefaultParameterValue(null)]
string ajaxUpdateContainerId,
[Optional, DefaultParameterValue(null)]
string fieldNamePrefix,
[Optional, DefaultParameterValue(null)]
string pageFieldName,
[Optional, DefaultParameterValue(null)]
string selectionFieldName,
[Optional, DefaultParameterValue(null)]
string sortFieldName,
[Optional, DefaultParameterValue(null)]
string sortDirectionFieldName);
// Properties
public string AjaxUpdateContainerId { get; }
public IEnumerable<string> ColumnNames { get; }
[Dynamic(new bool[] { false, true })]
public IEnumerable<object> DataSource { [return: Dynamic(new bool[] { false, true })] get; }
private Type ElementType { get; }
public string FieldNamePrefix { get; }
public bool HasSelection { get; }
private HttpContextBase HttpContext { get; }
public int PageCount { get; }
public string PageFieldName { get; }
public int PageIndex { get; set; }
private NameValueCollection QueryString { get; }
public IList<WebGridRow> Rows { get; }
public int RowsPerPage { get; }
public int SelectedIndex { get; set; }
public WebGridRow SelectedRow { get; }
public string SelectionFieldName { get; }
public string SortColumn { get; set; }
public SortDirection SortDirection { get; set; }
public string SortDirectionFieldName { get; }
public string SortFieldName { get; }
public int TotalRowCount { get; }
构造函数参数解释:
| 1 | Source | 此参数在WebGrid的构造函数中,为WebGrid指定数据源,如本例中的Model,即List<T_STUDENT> |
| 2 | columnNames | 在source中的字段的集合,如: columnNames:new []{"StudentID","StudentName"},指定要显示的列 |
| 3 | defaultSort | 指定默认排序的字段名 |
| 4 | rowsPerPage | 指定每一页显示多少行 |
| 5 | canPage | 是否允许分页,默认为true |
| 6 | canSort | 是否允许排序,默认为true |
| 7 | ajaxUpdateContainerId | 指定到对象的ID,例如本例中的DivGrid,当产生Ajax事件后,将更新后的数据show在这个ID的容器中。 |
| 8 | fieldNamePrefix | 给WebGrid产生的字符串加前缀,比如说在没有加前缀的时候Sorting链接为“/Home/Gridview?sort=StudentID&sortdir=ASC”,为其加完前缀grid_后为,字符链接“/Home/Gridview?grid_sort=StudentID&grid_sortdir=ASC”,即WebGrid中所有的参数都加上其前缀 |
| 9 | pageFieldName | 自定义分页QueryString的参数名称,比如说pageFieldName=”paging”,再加上面fieldNamePrefix加上的前缀grid_,那么生成的分页字条串就是“/Home/Gridview?grid_paging=2” |
| 10 | selectionFieldName | 自定义值来替换默认的查询字符串“行”字段,没有用过,等解释 |
| 11 | sortFieldName | 自定义查询排序QueryString的参数名称,比如说sortFieldName=”sortField”,那么生成的排序字符串就是“Home/Gridview?grid_sortField=StudentName&grid_sortdir=DESC” |
| 12 | sortDirectionFieldName | 自定义排序方向QueryString的参数名称,比如说sortDirectionFieldName=“sortDirectionField”,那么生成的排序串是“Home/Gridview?grid_sortField=StudentName&grid_sortDirectionField=DESC” |
属性解释
1 DataSource 获取绑定到的WebGrid的数据源
2 TotalRowCount 获取绑定到WebGrid的数据总行数
3 PageIndex 获取WebGrid总页数
4 SortDirection 获取或者设置WebGrid的排序方向
5 SelectedIndex 获取WebGrid的选择行的index
还有一些比较简单的属性,可以自己查一下,如果有不明白的可以联系我。如果有写的不好,请你指点,谢谢!
四、总结
通过本例的学习我们对MVC WebGrid有了更深一步的了角,知道了WebGrid Ajax的使用方法,知道了Ajax使用过程中与Search Conditions的绑定,了解了WebGrid中一些主要参数的功能。