由Ajax请求一般处理程序下载文件引发的问题后的一些总结

        这两天在做报表的导出功能,做了多年的开发,对代码的严谨性自然有了一些自我约束,对于这种与业务无关的通用外部处理,都觉得应该将其划分为外部的服务,做处理调用。所以我就想到采用一般处理程序来做文件的下载,前端使用Ajax做无刷新处理,代码如下:

function QueryExcel() {
var data = Ext.getCmp("frmMain").GetValues();// 获取json数据
Ext.Ajax.request({
url: '../Services/ReportExportHandler.ashx', // Webservice的地址以及方法名

jsonData: data,
method: 'POST',// poste 方式传递
success: function (result) {
    // 调用成功处理
},
failure: function (result) {
   // 调用失败处理
 }
});
}

一般处理程序实现文件下载的代码:

        string fileName = HttpUtility.UrlEncode(System.Text.Encoding.UTF8.GetBytes("111.csv"));
        context.Server.ScriptTimeout = 600;
        context.Response.ContentType = "application/octet-stream";
        context.Response.Charset = "gb2312";
        context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}\"", fileName));
        context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");

        DataTable dt = this.GetReportExcuteData(dto, paramsValues).Tables[0];
        byte[] bs =  ExportHelper.GetMemoryBytes(dt);
        context.Response.BinaryWrite(bs);
        context.Response.End();

将文件生成到内存的代码:

/// <summary>
        /// 从内存中获取字节数组
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns>字节数组</returns>
        public static byte[] GetMemoryBytes(DataTable dt)
        {
            // 先打印标头
            StringBuilder strColu = new StringBuilder();
            StringBuilder strValue = new StringBuilder();
            int i = 0;

            try
            {
                MemoryStream ms = new MemoryStream();
                byte[] bs;
                for (i = 0; i <= dt.Columns.Count - 1; i++)
                {
                    strColu.Append(dt.Columns[i].ColumnName);
                    strColu.Append(",");
                }

                strColu.Remove(strColu.Length - 1, 1); // 移出掉最后一个,字符
                bs = System.Text.Encoding.Default.GetBytes(strColu.ToString() + "\r\n");
                ms.Write(bs, 0, bs.Length);

                foreach (DataRow dr in dt.Rows)
                {
                    strValue.Remove(0, strValue.Length); // 移出

                    for (i = 0; i <= dt.Columns.Count - 1; i++)
                    {
                        strValue.Append(dr[i].ToString());
                        strValue.Append(",");
                    }

                    strValue.Remove(strValue.Length - 1, 1); // 移出掉最后一个,字符
                    bs = System.Text.Encoding.Default.GetBytes(strValue.ToString() + "\r\n");
                    ms.Write(bs, 0, bs.Length);
                }

                byte[] data = ms.GetBuffer();
                ms.Close();
                return data;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

在处理时发现点击按钮没有反应,起初我以为是一般处理程序内部写的有问题,但用浏览器的开发者工具查看请求和响应,发现响应的报头跟响应的的内容都与预期的相同,说明我的一般处理程序没有问题。后端没问题,那就是前端的问题了,由于对于Ajax的处理不是非常了解,所以一直也没有想到问题出在哪,后来我就发了个帖子问了一下,这才恍然大悟,原来Ajax可处理的数据格式是有要求的,引用资料原文:Jquery Ajax

另外还查到一篇关于 Ajax数据格式比较的博文,内容如下:

1.html
    优点:html片段实现起来只需要很小的工作量。这种格式的外部数据可以通过一种简单的方法加载并插入到页面中,甚至连回调函数都不必使用。无需遍历数据。
缺点:重用性差,外部文件必须与它们的目标容器紧密结合。
2.JavaScript
    JavaScript文件能投提供极大的灵活性,但它却不是一种真正的数据存储机制。
3.json
优点:
    json文件的结构使它可以方便地被重用。而且它们非常简洁,也容易阅读,读取速度快。
缺点:
    json文件中的错误可能导致页面上的脚本静默地终止运行,甚至还会带来其它的负面影响,因此,这种数据必须由信得过的人仔细进行构建。
4.xml
优点:
    xml文档的可移植性是当之无愧的王者,xml已经成为了web服务领域的“世界语”。xpath、dtd等都为它增色不少,能够对格式进行有效的验证。
缺点:
    xml格式的文件体积相对较大,解析和操作它们的速度要慢一些。

总结:
    通过对以上各种数据格式优缺点的分析,我们知道在不需要与其它应用程序共享数据的情况下,以html片段提供外部数据一般来说都是最简单的。如果数据需要重 用,而且其它应用程序也可能因此受影响,那么在性能和文件大小方面具有优势的json通常是不错的选择。而当远程应用程序未知时,xml则能够为良好的互 操作性提供最可靠的保证。


        发现了错误就记录以下,对于以后再发现类似的问题也方便查找解决方案。

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭