今天接到一个变态的需求,GridView中符合查询条件的所有的记录都导成csv文件,并下到客户端。虽然这个需求最后取消了,但是我感觉我的研究还是很有价值的,所以写出来,希望对大家有所帮助。由于最后没有具体实现,所以可能本文中的示例代码可能过于简单,请大家谅解。
首先叙述一下这个需求的难点:
1. 由于需求是要求到处特定条件的记录,而且这个特定的查询条件是存放在页面里面的,所以这个就要求Request要Postback到原来的页面
2. 由于空间是在UpdatePanel中的,但是我们返回的是文件流,所以就需要把下载文件的Postback的Request变为普通的经典的Postback
3. 由于最后的需要的是文件,所以此次Postback的Request返回的是一个文件流
下面会对三个难点一一解决:
1. 这个问题比较的简单,我们可以直接用方法__doPostBack(EventTarget, EventArgument);解决
2. 由于我们的空间是在UpdatePanel里面的,所以所有过于此控件的Postback都会被看成AjaxBack,而这又不是我们需要的,经过研究我发现可以用下面两句话解决此问题:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm._isCrossPost = true;
至此客户端的工作已经完成,相应的控件的事件就为:
function controlEvent()
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm._isCrossPost = true;
__doPostBack("ctl00$MainContent$Button1", '22');
return false;
}
3. 现在到了解决服务器端的问题了。借助ASP.NET的Ajax的服务器端的解决方案http://blog.csdn.net/robertdong1203/article/details/7775566
我们在控件的OnPreRender改写为:
protected override void OnPreRender(EventArgs e)
{
this.Page.SetRenderMethodDelegate(CsvExportRenderPage);
}
private void CsvExportRenderPage(HtmlTextWriter nullWriter, Control page)
{
HtmlForm form = this.Page.Form;
form.SetRenderMethodDelegate(new RenderMethod(this.CsvExportRenderForm));
}
private void CsvExportRenderForm(HtmlTextWriter nullWriter, Control form)
{
Response.ContentType = "application/pdf";
//此处添加生成文件的逻辑,然后将文件写入到Response中。简单起见,我直接读取现成的pdf文件
Response.WriteFile("Addison.Wesley.Domain.Driven.Design.pdf");
}