PostBack期间GridView.DataSource为null

时间:2014-11-14 14:05:28

标签: c# asp.net gridview datasource postback

我想在我的应用程序中从每个Gridview实现打印/下载csv。那些通过Datasources或直接通过

获取数据
gvSample.DataSource = Data;
gvSample.DataBind();

现在我的第一种方法是将下载按钮设置为页脚模板并处理下载

<asp:GridView ID="gvSample" runat="server">
 <PagerTemplate>
  <asp:ImageButton  ImageUrl="~/download.gif"  OnClick="dl_Click" runat="server" ID="dl"/>
 </PagerTemplate>
</asp:GridView>

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();           
}

但我无法访问数据。

3 个答案:

答案 0 :(得分:7)

DataSource中的{p> GridView并未以Postback的任何持久方式存储,因此您必须将其保存在某处(ViewstateSession)或您拥有从您的数据存储区再次请求它(Es您的数据库)。

对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分钟),如果用户显示该页面并在一小时后单击下载会话将为空

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);
    ...   
}

答案 1 :(得分:4)

您可以将数据保存在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不保存原始数据源,您必须将其保存在别处或按需重建

答案 2 :(得分:2)

  

您无法在编码时访问gv.DataSource

尝试使用SessionViewStates并保存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();    

}       
}