ASP.NET MVC实现(查询+分页)

   asp.net中我们知道有viewstate这样的页面级容器为我们保存表单数据,这样我们每次提交时数据都不会丢失,很容易的完成查询+分页的实现找过相关MVC分页的例子,都是扩展HtmlHelper方法来实现。我想大家在ASP.NET开发中都用过 wuqiAspNetPager分页控件以及daceyNSunPage用来开发Winform项目的分页控件非常方便的满足了大家的分页需求。那么我们来看下在MVC中的查询+分页是怎么实现的。(这里我用到了wuqi的mvcpager)

 下面例子是asp.net中的分页查询:

  前台代码:

< html >
< body >
< form  id ="form1"  runat ="server" >
部门编号:
< asp:TextBox  ID ="deptcode"  Width ="80px"  runat ="server" ></ asp:TextBox >
部门名称:
< asp:TextBox  ID ="deptname"  Width ="80px"  runat ="server"   ></ asp:TextBox >
< asp:Button  ID ="btnquery"  runat ="server"  Text ="查询"  onclick =" btnquery_Click" />
< table  class ="TableBlock"  width ="100%"  style ="margin-top: 10px;" >
              
< tr >
              
< th > 编号 </ th >
              
< th > 名称 </ th >
              
</ tr >
< asp:Repeater  ID ="TableBlockList"  runat ="server" >
  
< ItemTemplate >
              
< tr >
              
< td > <% # Eval ( " code " )   %> </ td >
              
< td > <% # Eval ( " name " )   %> </ td >
</ tr >
  
</ ItemTemplate >
  
</ asp:Repeater >
</ table >
</ form >
</ body >
</ html >

 后台代码:

 

protected   virtual  SelectSqlSection GetSelectSearch()
{
      SelectSqlSection select 
=  db.GetSelectSqlSection ();
      
if  ( ! string .IsNullOrEmpty (deptname.Text))  {                 
          select.Where (View_DeptQueryInfo.__name.Like(deptname.Text  
+   " % " ));
      }
      
if ( ! string .IsNullOrEmpty(deptcode.Text)){
          select.Where (View_DeptQueryInfo.__code.Like(deptcode.Text  
+   " % " ));
      }
      
return  select; 
}
protected   void  BindTable(Repeater rpt, AspNetPager anp)
{
      
int  countPage  =   0 ;
      DataTable dt 
= db.SelectPageToDataTable(GetSelectSearch (), anp.PageSize, anp.CurrentPageIndex, 
out  countPage);
      anp.RecordCount 
=  countPage;
      rpt.DataSource 
=  dt;
      rpt.DataBind();


    以上就完成了查询分页的功能,没什么特别的和我们做winform的差不多。第二次查询一样能获得表单内的值。

 

 

    那么asp.net mvc中怎么实现呢?用什么来保存表单数据呢?记得原来写java的时候我是用session这样笨拙的方法来保存查询提交后的方法来保存用户查询条件的。那么在asp.net mvc中我们该怎么实现呢?

  

 页面代码:

< html >
< body >
    
< form  id ="form1"  method ="post"  action ="/Dept/Dept"  runat ="server" >  
     部门名称:
< input  id ="deptname"  name =" deptname "  type ="text"  value ='<%=ViewData  ["deptname "] % > '/>
     部门编号:
< input  id ="deptcode"  name =" deptcode "  type ="text"  value ='<%=ViewData  ["deptcode "] % > '/> 
< input  id ="btnquery"  type ="submit"  value ="查询 " />
< table  class ="TableBlock"  width ="100%" >
        
< tr >  
            
< th > 编号 </ th >
            
< th > 部门名称 </ th >
       
</ tr >
< asp:MvcRepeater  ID ="MvcRepeater1"  Key ="deptlist"  runat ="server" >
            
< ItemTemplate >
              
< tr >  
              
< td  style ="width:5;" > <% Eval ( " code " ) %> </ td >
              
< td  style ="width:10;" > <% Eval ( " name " ) %> </ td >
              
</ tr >
            
</ ItemTemplate >
</ asp:MvcRepeater >    
</ table >
< div  class ="pager"  style ="width:100%;text-align:right;" >
        
< div  class ="pager"  align ="left"  style ="float: left; width: 40%;" >
<% = " 共  " +  ((Webdiyer.WebControls.Mvc.PagedList < DepartmentInfo > )ViewData [ " deptlist " ]).TotalPageCount  +   " "   +   ((Webdiyer.WebControls.Mvc.PagedList < DepartmentInfo > )ViewData [ " deptlist " ]).TotalItemCount  +   " " %> </ div >
< div  align ="right"  class ="pager"  style ="width: 60%; float: left;" >   <% = Html.Pager < DepartmentInfo >  ((Webdiyer.WebControls.Mvc.PagedList < DepartmentInfo > )ViewData [ " deptlist " ],  new  PagerOptions() { PageIndexParameterName  =   " id " , CurrentPagerItemWrapperFormatString  =   " <span class=\ " cpb \ " > {0}</span> " , NumericPagerItemWrapperFormatString  =   " <span class=\ " item \ " > {0}</span> " , CssClass  =   " pages " , SeparatorHtml  =   "" ,IsPost = true  }) %> </ div >
    
</ div >
    
</ form >
</ body >
</ html >

 

 

      首先用到了Repeater,在mvcRepeater的使用需要我们重写一下。如果想用for循环来实现也可以。我们继承Repeater然后重写OnLoad(EventArgs e) 方法得到Controller中放入ViewData的数据。我们添加一个公开的属性来取得对应ViewDate的值。

 

     Repeater重写:

    public   string  Key {  get set ; }
    
// 绑定数据 
     protected   override   void  OnLoad(EventArgs e)
    {
       
this .DataSource  =  ( base .Page  as  ViewPage).ViewData[ this .Key];

       
this .DataBind();    

       
base .OnLoad(e);
    }

    这样就得到我们想要的 MVC 中的 Repeater ,因为 Repeater 必须放在 runat="server" form 中所以这里 action 没有使用 UrlHepler 给我们提供的方法来写。

    我们把查询条件放入 ViewData 为了提交后的保存与显示。

 

< input  id ="deptname"  name =" deptname "  type ="text"  value ='<%=ViewData ["deptname "] % > '/>

   后台保存:

public  ActionResult Dept ( int ?  id)
        {
            ViewData [
" deptlist " =  BindTable(id);
            
return  View();
        }
        
protected  Webdiyer.WebControls.Mvc.PagedList < DepartmentInfo >  BindTable( int ?  id)
        {
            
int  countPage  =   0 ;
            List
< DepartmentInfo >  dt  =  db.SelectPageToList(GetSelectSearch(),  10 , id  ??   1 out  countPage);
            Webdiyer.WebC ontrols.Mvc.PagedList
< DepartmentInfo >  p  =   new  Webdiyer.WebControls.Mvc.PagedList < DepartmentInfo > (dt, id  ??   1 10 , countPage);
            
return  p;
        }
        
protected   virtual  SelectSqlSection GetSelectSearch()
        {
            SelectSqlSectio n select 
=  db.GetSelectSqlSection();
            select.OrderBy (DepartmentInfo.__ordernumber.Asc);
            
if  ( ! string .IsNullOrWhiteSpace(Request[ " deptname " ]))
            {
                
select.Where(DepartmentInfo.__name.Like( " % "   +  GetFormValue( " deptname " +   " % " ));
            }
            
if  ( ! string .IsNullOrWhiteSpace(Request[ " deptcode " ]))
            {
               
select.Where(DepartmentInfo.__code.Like( " % "   +  GetFormValue( " deptcode " +   " % " ));
            }
            
return  select;
        }
        
private   object  GetFormValue( string  name)
        {
            ViewData [name] 
=  Request[name];
            
return  ViewData[name];
        }

 

      这里出现问题了,在查询时候的确可以获得表单的值,也可以这样保存显示,那么查询后点分页怎么办?分页可是a标签,难道让a标签也提交么? 

OK ,那么我们就来实现 a 标签的提交,我们就来给它分页时做提交功能。

   

     因为每次分页都提交表单可能不是各个场景都需要,这里我对 PagerOptions类扩展了2个属性一个是 ispost(分页是否提交,默认是false    FormName(提交表单id,这里默认是 asp.net生成的form1)。

   

     再来看怎么生成控件到页面,我们看PagerBuilder类,找到GeneratePagerElement方法,看最后一句String.Format ("<a href='{0}'>{1}</a>", url, item.Text));默认是生成只带连接的a标签,我们来改造他吧。

  

 

我们重新写这个方法名字就叫GeneratePagerElementPost,我们把a 标签的href执行一段脚本,把刚才那句替换为 String.Format("<a href='javascript:_PagePostSubmit (\"{0}\")'>{1}</a>", url, item.Text));

   

这个js方法 就是用来点击a标签进行表单的提交的。那么我们看这个方法是怎么实现和生成到页面的。找到RenderPager方法,我们拉到方法最后看到如下代码,这里是添加脚本到客户端。

  

 

    if (!string.IsNullOrEmpty(pagerScript))

     pagerScript = "<script language=\"javascript\" type=\"text/javascript\">" + pagerScript + "</script>";

     在这个方面上面添加一下代码:首先我们判断下客户端是否需要每次分页都提交页面,然后加入我们的_PagePostSubmit这个js方法

   

    if (_pagerOptions.IsPost)

    {

     //通过 _pagerOptions.FormName获得用户选定表单名称,修改其 action,然后提交。

         pagerScript += " function _PagePostSubmit(href){ document.forms['" + _pagerOptions.FormName + "'].action=href;document.forms['" + _pagerOptions.FormName + "'].submit();}";

    }

  

 

    Ok,这样每个 a标签都能提交表单了,我们在页面添加下面代码就完成了查询+分页的实现

    

 

<% = Html.Pager < DepartmentInfo > ((Webdiyer.WebControls.Mvc.PagedList < DepartmentInfo > )ViewData [ " deptlist " ],  new  PagerOptions() { PageIndexParameterName  =   " id " , CurrentPagerItemWrapperFormatString  =   " <span class=\ " cpb \ " > {0}</span> " , NumericPagerItemWrapperFormatString  =   " <span class=\ " item \ " > {0}</span> " , CssClass  =   " pages " , SeparatorHtml  =   "" ,IsPost = true  }) %>

 

      把刚加的 IsPost属性变为 true,默认FormName=form1这里就没有在赋值了。

   

    实现DEMO:ASP.NET MVC查询+分页 DEMO

    修改后的MVCPAGER:  ModifyPostMvcPagerSrc

你可能感兴趣的:(asp.net)