您当前的位置:KKBlog > 学无止境 > ASP.NET

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);
        }
二维码
意见反馈 二维码