GridView UpdatePanel RowCommand 实现下载文件
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" Width="100%" Font-Size="Small" PageSize="8>
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="comfirmbtn" runat="server" ImageUrl="images/dataCorrection.png" ToolTip="生成确认单" CommandName="confirm" CommandArgument='<%#Eval("PSCode")+"*"+Eval("PSName")%>' OnInit="ImgBtnInit"></asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
.........................
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>问题:由于UpdatePanel的影响,导致在页面中点击ImageButton时会提示下面所示的错误,不会弹出所期望的下载页面 。
解决方法:在ImageButton的OnInit事件中用一下scriptManager的RegesterPostBcakControl((Control)sender)方法。
后台:
protected void ImgBtnInit(object sender, EventArgs e)
{
ScriptManager1.RegisterPostBackControl((Control)sender);
}由于在updatepanel中无法使用Response.Write(...),所以如果在UpdatePanel内的按钮的事件响应代码中含有Response.Write(...)就会出错,具体什么原因我不知道;
解决的办法是,在updatepanel的trigger中将该按钮添加为PostbackTrigger。之后该按钮的事件响应函数就可以使用Response.Write()了。
如果我的按钮不是独立存在的,而是gridview的一个模板字段内的按钮,那么在添加的时候只能将整个gridview作为postback的trigger,那将会殃及gridview其他无刷新的功能,解决办法,只要在那个模板字段内控件的init事件中用一下scriptManager的RegesterPostBcakControl((Control)sender);就可以了
实例演示:
前台:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:GridView ID="gvData" runat="server" AutoGenerateColumns="False" DataKeyNames="RoleName,RoleId,ColumnId" EmptyDataText="未找到信息" CellPadding="4" SkinID="gridviewSkin1" Style="width: 650px;" OnRowCancelingEdit="gvData_RowCancelingEdit" OnRowEditing="gvData_RowEditing" OnRowUpdating="gvData_RowUpdating" OnRowDataBound="gvData_RowDataBound" OnRowCommand="gvData_RowCommand"> <Columns> <asp:TemplateField HeaderText="操作"> <asp:LinkButton ID="lnkbtn_ExportAuthority" runat="server" CommandArgument="<%# ((GridViewRow)Container).RowIndex %>" CommandName="ExportAuthority" OnInit="lnkbtn_ExportAuthority_Init">导出权限</asp:LinkButton> </asp:TemplateField> </Columns> </asp:GridView> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" /> <%--<asp:AsyncPostBackTrigger ControlID="gvData" /> 这里不需要--%> </Triggers> </asp:UpdatePanel>
后台:
protected void gvData_RowCommand(object sender, GridViewCommandEventArgs e)
{
//导出权限
if (e.CommandName == "ExportAuthority")
{
int _index = Convert.ToInt32(e.CommandArgument);
Guid _appId = new Guid(this.hid_AppId.Value);
Guid _roleId = new Guid(gvData.DataKeys[_index][1].ToString());
int _columnId = int.Parse(gvData.DataKeys[_index][2].ToString());
string _fileName = string.Format("{0}-{1}-角色权限数据-{2}.txt", ((Label)gvData.Rows[_index].FindControl("lblArea")).Text, ((Label)gvData.Rows[_index].FindControl("lbl_description")).Text, DateTime.Now.ToString("yyyyMMdd"));
ExportAuthority(_appId, _roleId, _columnId, _fileName);
}
}
//导出权限
private void ExportAuthority(Guid appId, Guid roleId, int columnId, string fileName)
{
try
{
string _roleAuthority = "", _result = "";
BLL.aspnet_RolesAuthority bll_RoleAuthority = new BLL.aspnet_RolesAuthority();
Model.aspnet_RolesAuthority model_RoleAuthority = new Model.aspnet_RolesAuthority();
model_RoleAuthority = bll_RoleAuthority.GetModel(appId, roleId, columnId);
if (!object.Equals(model_RoleAuthority, null))
{
_roleAuthority = model_RoleAuthority.ModuleStr;
}
_result = DESEncrypt.Encrypt(_roleAuthority);
//保存文档,并下载
string _folderName = "/temp/";
string _serverFolderName = Server.MapPath(_folderName);//临时文件夹名
Random r = new Random();
string _fileName = fileName;// DateTime.Now.ToString("yyyyMMddHHmmss") + r.Next(1000, 9999) + "-RoleAuthority-export.txt";//文件名
string _tempFilePath = _serverFolderName + _fileName;//完整的文件路径
if (!Directory.Exists(_serverFolderName))
{
//创建临时目录
Directory.CreateDirectory(_serverFolderName);
}
//保存生成的文档
FileStream fs1 = new FileStream(_tempFilePath, FileMode.Create, FileAccess.Write);//创建写入文件
StreamWriter sw = new StreamWriter(fs1);
sw.WriteLine(_result);//开始写入值
sw.Close();
fs1.Close();
//方法一:
////以字符流的形式下载文件
//FileStream fs = new FileStream(_tempFilePath, FileMode.Open);
//byte[] bytes = new byte[(int)fs.Length];
//fs.Read(bytes, 0, bytes.Length);
//fs.Close();
//HttpContext.Current.Response.ContentType = "application/octet-stream";
////通知浏览器下载文件而不是打开
//HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8));
//HttpContext.Current.Response.BinaryWrite(bytes);
//HttpContext.Current.Response.Flush();
//HttpContext.Current.Response.End();
//方法二:
FileInfo fileInfo = new FileInfo(_tempFilePath);
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
//添加头信息,为"文件下载/另存为"对话框指定默认文件名,设定编码为UTF8,防止中文文件名出现乱码
//把attachment改为online 则表示在线查看
Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8));
//添加头信息,指定文件大小,让浏览器能够显示下载进度
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.AddHeader("Content-Transfer-Encoding", "binary");
//指定返回的是一个不能被客户端读取的流,必须被下载 Response.ContentType = "application/octet-stream";
Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
// 把文件流发送到客户端
Response.WriteFile(fileInfo.FullName);
Response.Flush();
Response.End();
}
catch (Exception ex)
{
System.Web.UI.ScriptManager.RegisterStartupScript(this.UpdatePanel1, this.GetType(), "MyScript", string.Format("alert(\"错误:{0}\");", ex.Message), true);
}
}
//这里是关键,不然不会弹出下载文件的提示框
protected void lnkbtn_ExportAuthority_Init(object sender, EventArgs e)
{
ScriptManager1.RegisterPostBackControl((Control)sender);
}

添加评论