PostBack期间GridView.DataSource为null
我想在我的应用程序中从每个Gridview实现打印/下载csv。 那些通过Datasources或直接获取数据
gvSample.DataSource = Data; gvSample.DataBind();
现在我的第一种方法是将下载按钮设置为页脚模板并在那里处理下载
和
protected void dl_Click(object sender, ImageClickEventArgs e) { GridView gv = (GridView)this.Parent.Parent.Parent.Parent; string csv = ToCSV(gv.DataSource); //gv.DataSource is null, DatasourceID aswell Response.ContentType = "application/csv"; Response.AddHeader("content-disposition", "attachment; filename=file.csv"); Response.Write(csv); Response.End(); }
但我无法访问数据。
GridView
DataSource
不会以任何持久的方式存储在Postback
因此您必须将其保存在某个位置( Viewstate或Session ),或者您必须再次从数据存储区(Es your db)请求它。
快速解释3种方法:
VievState :保存在页面的隐藏字段中,因此不建议用于大型数据集,因为您的页面可能会变成多MB。 它的优点是它保存在页面中,因此它不会过期
ViewState["Data"] = GetData(); gvSample.DataSource = ViewState["Data"]; gvSample.DataBind(); ... protected void dl_Click(object sender, ImageClickEventArgs e) { string csv = ToCSV(ViewState["Data"]); ... }
会话 :保存在服务器内存中,因此您“完全”没有大小问题,但会话不会永远持续(通常为30分钟),如果用户显示该页面并在一小时后单击下载会话将为null
Session["Data"] = GetData(); gvSample.DataSource = Session["Data"]; gvSample.DataBind(); ... protected void dl_Click(object sender, ImageClickEventArgs e) { string csv = ToCSV(Session["Data"]); ... }
从数据存储请求您从数据库中请求数据,以便完成另一次往返,并且数据可以与用户看到的内容不同
gvSample.DataSource = GetData(); gvSample.DataBind(); ... protected void dl_Click(object sender, ImageClickEventArgs e) { string csv = ToCSV(GetData()); ... }
只是一个建议:
你可以直接使用gvSample
访问网格更简单,这样你就不会破坏你的html ……:
protected void dl_Click(object sender, ImageClickEventArgs e) { //GridView gv = (GridView)this.Parent.Parent.Parent.Parent; //string csv = ToCSV(gv.DataSource); //gv.DataSource is null, DatasourceID aswell string csv = ToCSV(gvSample.DataSource); ... }
您可以将数据保存在ViewState
(大型数据集未提供!!!)
gvSample.DataSource = Data; ViewState["Data"] = Data; gvSample.DataBind();
protected void dl_Click(object sender, ImageClickEventArgs e) { var ds = (ProperDataType)ViewState["Data"]; // TODO: check for nulls string csv = ToCSV(ds); //gv.DataSource is null, DatasourceID aswell Response.ContentType = "application/csv"; Response.AddHeader("content-disposition", "attachment; filename=file.csv"); Response.Write(csv); Response.End(); }
此外,您可以基于gridview重建数据,例如
var ds = new ProperDataSource(); foreach(GridViewRow row in gvSample.Rows) { dRow data = new dRow(); foreach(TableCell cell in row.Cells) { ds.Add("column1", cell.Text); } ds.Add(dRow); } string csv = ToCSV(ds); //gv.DataSource is null, DatasourceID aswell Response.ContentType = "application/csv"; Response.AddHeader("content-disposition", "attachment; filename=file.csv"); Response.Write(csv); Response.End();
当然,您必须将此片段与您的特定数据结构相匹配……但这是一般的想法。
GridViews不保存它的原始数据源,您必须将其保存在别处或按需重建它
您无法在编码时访问它gv.DataSource
尝试使用Session
或ViewStates
并保存DataTable
gvSample.DataSource = Data; gvSample.DataBind(); Session["MyTable"]=Data;
将Session
转换为DataTable
并传递给Method
protected void dl_Click(object sender, ImageClickEventArgs e) { if(Session["MyTable"]==null) { string csv = ToCSV(DataTable(Session["MyTable"]) ); Response.ContentType = "application/csv"; Response.AddHeader("content-disposition", "attachment; filename=file.csv"); Response.Write(csv); Response.End(); } }