由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則能夠爲良好的互 操作性提供最可靠的保證。


        發現了錯誤就記錄以下,對於以後再發現類似的問題也方便查找解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章