asp.net中下载文件的问题

时间:2022-05-13 09:21:56

今天解决web的文件下载问题,下载的方法网上很多,不过我的下载有点特殊:

1、下载按钮在gridview中,是模板列的linkButton;

2、使用了ajax控件;

所以,在下载时总是报错,通过查找资料,解决方法如下:

1、先说ajax控件的问题:

如果下载按钮在ajax控件上,需要添加Triggers节点,如下:

aspx:

<asp:UpdatePanel ID="UpdatePanel3" runat="server">
<ContentTemplate>

<asp:Button ID="btnImportModel" Text="导入模板" runat="server"  CssClass="buttonSkin" onclick="btnImportModel_Click"/>

</ContentTemplate>

<Triggers>
<asp:PostBackTrigger ControlID="btnImportModel" />
</Triggers>
</asp:UpdatePanel>

aspx.cs:

protected void btnImportModel_Click(object sender, EventArgs e)
{

//服务器的路径地址文件夹,在根目录对应的文件相关的FileTempletModel下;如本系统的生成的文件在(根目录-MenuWFrm-JCSZ)下的FileTempletModel里
string savePath = HttpContext.Current.Server.MapPath("FileTempletModel");
if (!System.IO.Directory.Exists(savePath))
{//如果没有文件夹,则建立
System.IO.Directory.CreateDirectory(savePath);
}
savePath = savePath + "\\" + row.Cells[2].Text + ".xml";//服务器上的文件名称:文件夹路径 + 模板名称 + 后缀名(.xml)

DataSet ds = bllTemplet.ExportModelForDS(templetID);//获取数据
ds.WriteXml(savePath);//数据导出到文件中(服务器上)

GC.Collect();

string filePath = savePath;//+ ".xml";//服务器上的文件名称,用于从服务器下载到客户端上
if (System.IO.File.Exists(filePath))
{//将服务器上的文件下载到客户端上
System.IO.FileInfo file = new System.IO.FileInfo(filePath);
Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8"); //解决中文乱码
Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(file.Name)); //解决中文文件名乱码
Response.AddHeader("Content-length", file.Length.ToString());//下载时显示进度条
Response.ContentType = "appliction/octet-stream";

/* 微软为Response对象提供了一个新的方法TransmitFile来解决使用Response.BinaryWrite 下载超过400mb的文件时导致Aspnet_wp.exe进程回收而无法成功下载的问题。 代码如下: */
Response.TransmitFile(filePath, 0, file.Length); //这个路径是在根目录下
Response.Flush();
Response.End();
}

}

单击按钮的事件没有变化,仅仅需要在前台UpdatePanel中添加上Triggers节点,将按钮的ID存放进即可。

2、gridview中的模板列中按钮的问题:

在gridview中的模板列使用下载按钮,有一个问题,那就是无法找到该按钮ID,那么Triggers节点中就无法保存,这样点击下载报错。解决方法如下:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>

<asp:GridView ID="gv_show" runat="server"  onrowcommand="gv_show_RowCommand" onrowcreated="gv_show_RowCreated">

<Columns>

<asp:TemplateField HeaderText="操作">
<ItemStyle HorizontalAlign="center" Width="10%"></ItemStyle>
<ItemTemplate>

<asp:LinkButton ID="btn_ExportModel" runat="server" BackColor="Transparent" BorderStyle="None"
CommandName="b_exportModel" ForeColor="#3a6ea5" Text="导出" OnInit="btn_ExportModel_Init"></asp:LinkButton>

</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

</ContentTemplate>

</asp:UpdatePanel>

aspx.cs:

protected void btn_ExportModel_Init(object sender, EventArgs e)
{//不知道做什么用,但是没这段话,无法执行下载操作
ScriptManager scriptManager = (ScriptManager)((Page)HttpContext.Current.Handler).FindControl("ScriptManager1");//获取父页面ScriptManager1控件
scriptManager.RegisterPostBackControl((Control)sender);

//从结果来看,该方法是为了给Triggers中的PostBackTrigger赋值
}

按钮的方法和正常一样,没什么变化:

protected void gv_show_RowCommand(object sender, GridViewCommandEventArgs e)
{
int num = int.Parse(e.CommandArgument.ToString());
GridViewRow row = this.gv_show.Rows[num];
string templetID = this.gv_show.DataKeys[num]["GLVCHTempletID"].ToString().Trim();//主键

if (e.CommandName == "b_exportModel")
{

#region//导出模板

//服务器的路径地址文件夹,在根目录对应的文件相关的FileTempletModel下;如本系统的生成的文件在(根目录-MenuWFrm-JCSZ)下的FileTempletModel里
string savePath = HttpContext.Current.Server.MapPath("FileTempletModel");
if (!System.IO.Directory.Exists(savePath))
{//如果没有文件夹,则建立
System.IO.Directory.CreateDirectory(savePath);
}
savePath = savePath + "\\" + row.Cells[2].Text + ".xml";//服务器上的文件名称:文件夹路径 + 模板名称 + 后缀名(.xml)

DataSet ds = bllTemplet.ExportModelForDS(templetID);//获取数据
ds.WriteXml(savePath);//数据导出到文件中(服务器上)

GC.Collect();

string filePath = savePath;//+ ".xml";//服务器上的文件名称,用于从服务器下载到客户端上
if (System.IO.File.Exists(filePath))
{//将服务器上的文件下载到客户端上
System.IO.FileInfo file = new System.IO.FileInfo(filePath);
Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8"); //解决中文乱码
Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(file.Name)); //解决中文文件名乱码
Response.AddHeader("Content-length", file.Length.ToString());//下载时显示进度条
Response.ContentType = "appliction/octet-stream";
//Response.ContentType = "application/x-zip-compressed";
//Response.WriteFile(file.FullName);

/* 微软为Response对象提供了一个新的方法TransmitFile来解决使用Response.BinaryWrite 下载超过400mb的文件时导致Aspnet_wp.exe进程回收而无法成功下载的问题。 代码如下: */
Response.TransmitFile(filePath, 0, file.Length); //这个路径是在根目录下
Response.Flush();
Response.End();
}

#endregion
}

}

protected void gv_show_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton btn = (LinkButton)e.Row.FindControl("btn_ExportModel");

if (btn != null)
{//导出模板
btn.CommandArgument = e.Row.RowIndex.ToString();
}

}
}

综上,可以看出下载的方法还是常见的方法,但是在使用ajax的UpdatePanel后,需要添加:

<Triggers>
<asp:PostBackTrigger ControlID="btnExport" />
</Triggers>

如果是在gridview中使用下载按钮,需要想办法找到该按钮的ID,并实现asp:PostBackTrigger赋值