技术开发 频道

ASP.NET MVC3新功能之WebGrid查询绑定

    【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:

public ActionResult Gridview()
         {
             DALDataContext da
= new DALDataContext();
             var result
=da.T_STUDENTs.ToList();
             this.ViewData.Model
= result;
             return View();
         }

 

  View:(如果对其中的属性不明白,请参考下面四中的内容

@using MVC3Tutorial;
@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的使用,得到结果如下:

1 

 

  2. WebGrid Sorting(排序) Ajax的实现

  我们看,在上面的View代码中黄色背景表示的是创建WebGrid对象实例,其中有这样一行ajaxUpdateContainerId:"DivGrid",他表示的是当WebGrid发生AjaxUpdate事件后,将更新后内容显示到指定的元素中。在我们示例中,我们指定的是一个Div对象。也就是说我们期望得到的结果是,当我们点击标题行的列进行排序后,应该把排序后的新内容放到这个Div中,并且是Ajax操作。但是在实际操作中,浏览器会提示如下信息:

1
 

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

1
 

  我们可以看到,他生成的是一个JQuery的操作方式,所以我们必须引用JQuery的类库,如下(本下在_Layout.cshtml中加载的):

<head>
    
<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代码修改如下:

@using MVC3Tutorial; 
@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.,如下图所示:

1
 

  那么当我们点击Sorting的时候如何它才能保持现有的查询条件不变呢?我所采取的策略是使用TempData保存现有的查询条件,所以我们就需要在Action中获取查询条件并将其放放TempData中,当Action返回时,我们在view中把现有的TempData再次的进行绑定,因为WebGrid的Sorting他请求的是一个URL,而不是提交事件,所以当点击Sorting的时候,他并不会收集form中的对象,但是因为之前的一次查询,我们将查询条件存入了TempData中,所以现在我们可以从TempData中取出查询条件,Action代码修改如下:

   public ActionResult Gridview()
         {
             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是否具备如分页、排序等功能。主要参数如下:

// Methods
      
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; }

  

  构造函数参数解释:

1Source此参数在WebGrid的构造函数中,为WebGrid指定数据源,如本例中的Model,即List<T_STUDENT>
2columnNames在source中的字段的集合,如: columnNames:new []{"StudentID","StudentName"},指定要显示的列
3defaultSort指定默认排序的字段名
4rowsPerPage指定每一页显示多少行
5canPage是否允许分页,默认为true
6canSort是否允许排序,默认为true
7ajaxUpdateContainerId指定到对象的ID,例如本例中的DivGrid,当产生Ajax事件后,将更新后的数据show在这个ID的容器中。
8fieldNamePrefix给WebGrid产生的字符串加前缀,比如说在没有加前缀的时候Sorting链接为“/Home/Gridview?sort=StudentID&sortdir=ASC”,为其加完前缀grid_后为,字符链接“/Home/Gridview?grid_sort=StudentID&grid_sortdir=ASC”,即WebGrid中所有的参数都加上其前缀
9pageFieldName自定义分页QueryString的参数名称,比如说pageFieldName=”paging”,再加上面fieldNamePrefix加上的前缀grid_,那么生成的分页字条串就是“/Home/Gridview?grid_paging=2”
10selectionFieldName自定义值来替换默认的查询字符串“行”字段,没有用过,等解释
11sortFieldName自定义查询排序QueryString的参数名称,比如说sortFieldName=”sortField”,那么生成的排序字符串就是“Home/Gridview?grid_sortField=StudentName&grid_sortdir=DESC”
12sortDirectionFieldName自定义排序方向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中一些主要参数的功能。

0
相关文章