PostBack期间GridView.DataSource为null

fub*_*ubo 2 c# asp.net postback gridview datasource

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

gvSample.DataSource = Data;
gvSample.DataBind();
Run Code Online (Sandbox Code Playgroud)

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

<asp:GridView ID="gvSample" runat="server">
 <PagerTemplate>
  <asp:ImageButton  ImageUrl="~/download.gif"  OnClick="dl_Click" runat="server" ID="dl"/>
 </PagerTemplate>
</asp:GridView>
Run Code Online (Sandbox Code Playgroud)

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();           
}
Run Code Online (Sandbox Code Playgroud)

但我无法访问数据.

gia*_*min 7

DataSourcein GridView不以任何持久的方式存储,Postback因此您必须将其保存在某个位置(ViewstateSession),或者您必须再次从数据存储区(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"]);
    ...   
}
Run Code Online (Sandbox Code Playgroud)

会话:保存在服务器内存中,因此您"完全"没有大小问题,但会话不会永远持续(通常为30分钟),如果用户显示该页面并在一小时后单击下载会话将为null

Session["Data"] = GetData();
gvSample.DataSource = Session["Data"];
gvSample.DataBind();

...

protected void dl_Click(object sender, ImageClickEventArgs e)
{
    string csv = ToCSV(Session["Data"]);
    ...   
}
Run Code Online (Sandbox Code Playgroud)

从数据存储请求您从数据库中请求数据,以便完成另一次往返,并且数据可以与用户看到的内容不同

gvSample.DataSource = GetData();
gvSample.DataBind();

...

protected void dl_Click(object sender, ImageClickEventArgs e)
{
    string csv = ToCSV(GetData());
    ...   
}
Run Code Online (Sandbox Code Playgroud)

只是一个建议:

您可以直接使用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);
    ...   
}
Run Code Online (Sandbox Code Playgroud)


cpa*_*eco 5

您可以将数据保存在ViewState(不推荐用于大型数据集!!!),大致

gvSample.DataSource = Data;
ViewState["Data"] = Data;
gvSample.DataBind();
Run Code Online (Sandbox Code Playgroud)
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();           
}
Run Code Online (Sandbox Code Playgroud)

此外,您可以根据 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();  
Run Code Online (Sandbox Code Playgroud)

当然,您必须使此代码段适合您的特定数据结构……但这是总体思路。

GridViews 不保存它的原始数据源,您必须将其保存在别处或按需重建