Response.WriteFile两次写入内容

时间:2012-06-26 18:17:52

标签: c# asp.net download response response.write

这是我的代码..

 string attachment = "attachment; filename=Call-Details-Report-" + startDate.SelectedDate.Value.ToString("MM-dd-yyyy") + ".csv";
        Response.Clear();
        Response.ClearHeaders();
        Response.ClearContent();
        Response.AddHeader("Content-Disposition", attachment);
        Response.ContentType = "text/csv";
        Response.AddHeader("Pragma", "public");
        Response.WriteFile(downloadLocation+"\\"+fileName);
        Response.End();

我正在使用上面的代码从一个位置下载一个csv文件。但令人惊讶的是,内容被写入两次或几次写入我下载的文件中,但实际上它并非如此,因为服务器上的文件.I我在c#中编写代码。 上面的代码在本地机器上完美运行,但问题出在生产服务器上。

这是我的完整方法

 private void DownloadReport(string query)
{
    string downloadFolderPath = "";
    string filePath = "";
    string dbAndApplicationServerStatus = ConfigurationManager.AppSettings["SameDBAndApplicationServer"] != null ? ConfigurationManager.AppSettings["SameDBAndApplicationServer"] : "1";
    if (dbAndApplicationServerStatus == "0")
    {
        Log.Write("So the DB And Application are on differrent servers,hence trying to read Download folder path on DB Server....");
        downloadFolderPath = ConfigurationManager.AppSettings["ReportDownloadLocation"] != null ? ConfigurationManager.AppSettings["ReportDownloadLocation"] : "-1";
        Log.Write("Download Path is " + downloadFolderPath);
    }
    else
    {
        Log.Write("So the DB and Application and Db are on same server......");
        downloadFolderPath = Server.MapPath("Download");
        downloadFolderPath = downloadFolderPath.Replace("\\", "//");
        if (!Directory.Exists(downloadFolderPath))
        {
            Directory.CreateDirectory(downloadFolderPath);
        }
        Log.Write("Download Path is " + downloadFolderPath);
    }
    string status="";
    StringBuilder headerQuery = new StringBuilder();
    StringBuilder rowQuery = new StringBuilder();
    StringBuilder sqlQuery = new StringBuilder();
    filePath = downloadFolderPath;
    string folderName = DateTime.Now.ToString("MM-dd-yyyy");

    string timeStamp = DateTime.Now.ToString("MM-dd-yy-HH-mm-ss");
    string fileName = "Call-Details-Report-" + startDate.SelectedDate.Value.ToString("MM-dd-yyyy") + "_" + timeStamp + ".csv";
    filePath = filePath + "/" + fileName;

    bool commaRequired = false;

    sqlQuery.Append("SELECT * INTO OUTFILE '");
    sqlQuery.Append(filePath);
    sqlQuery.Append("' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n' FROM (");
    headerQuery.Append("Select ");
    rowQuery.Append("(Select ");

    #region Creating Query
    /*Sql Query is Created  in this region*/
    #endregion



    if (!CdrSearch.WriteReportToFile(sqlQuery.ToString(),out status))
    {
        Log.Write("Failed to generate the file to download......");
        WebPagesHelper.ShowMessage(ref lblMessage, WebPagesHelper.MessageType.Message, status);
    }
    else
    {
        Log.Write("Succesfully generated file to Download");
        string downloadLocation = Server.MapPath("Download");
        if (dbAndApplicationServerStatus == "0")
        {
            WebClient webClient = new WebClient();
            string path = ConfigurationManager.AppSettings["DownloadURL"] != null ? ConfigurationManager.AppSettings["DownloadURL"].ToString() : "";

            if (!Directory.Exists(downloadLocation))
            {
                Directory.CreateDirectory(downloadLocation);
            }
            if (File.Exists(downloadLocation + "\\" + fileName))
            {
                File.Delete(downloadLocation + "\\" + fileName);
            }
            webClient.DownloadFile(path + fileName, downloadLocation + "\\" + fileName);

        }
        Log.Write("Configured Download Location on Application" + downloadLocation);
        string attachment = "attachment; filename=Call-Details-Report-" + startDate.SelectedDate.Value.ToString("MM-dd-yyyy") + ".csv";
        Response.Clear();
        Response.ClearHeaders();
        Response.ClearContent();
        Response.AddHeader("Content-Disposition", attachment);
        Response.ContentType = "text/csv";
        Response.AddHeader("Pragma", "public");

        Log.Write(downloadLocation + "\\" + fileName);

        Response.WriteFile(downloadLocation+"\\"+fileName);
        Response.SetCookie(new HttpCookie("DStatus", "Completed"));
        Response.End();
    }
}

上面的方法只需点击一个按钮即可立即调用一次,所以这里没有任何循环问题。

3 个答案:

答案 0 :(得分:0)

您可以查看以下行的含义:

webClient.DownloadFile(path + fileName, downloadLocation + "\\" + fileName); 

Response.WriteFile(downloadLocation+"\\"+fileName); 

尝试通过评论其中一个,如果他们真的在做同样的事情。 作为一项安全措施,请在下载完成之前禁用该按钮。

当我尝试以下代码(甚至在IIS上发布)时,它只是按预期下载一次。

 protected void Button1_Click(object sender, EventArgs e)
        {
            string attachment = "attachment; filename=Call-Details-Report-" + DateTime.Now.ToString("MM-dd-yyyy") + ".txt";
            Response.ContentType = "text/html";
            Response.AddHeader("Content-Disposition", attachment); 
            Response.AddHeader("Pragma", "public");

            Response.WriteFile(@"C:\test.txt");
            Response.SetCookie(new HttpCookie("DStatus", "Completed")); 

            Response.End();
        }

答案 1 :(得分:0)

显然有些事情发生了变化。您已经说过它可以在dev中运行但不是Prod - 您是否在两个environemts中使用相同的服务器配置(即您在开发中使用1个服务器但在prod中使用2个服务器?)

假设我已理解您的代码,您可能有3个步骤......

  • 从SQL生成报告并将其写入文件
  • 如果文件存储在其他服务器上,请将其下载到Web服务器
  • 服务

所以,在更复杂的场景中(我假设生产是这样),在这个过程的哪一步你开始看到双重条目?在服务器上,报告是在Web服务器副本上生成的,还是仅在从Web服务器获取报告后在客户端生成的?

我看不出为什么你的代码向客户端提供服务的代码会复制数据的原因,所以只能假设它在某个时刻之前发生。

如果你可以使用Firebug / Fiddler / ???会很有帮助将传输的确切内容从网络服务器发布到客户端

(顺便说一下,您可能希望查看System.IO.Path类来操作路径,它会使您的代码更具可读性和健壮性 - 不再担心拖尾斜杠!)

答案 2 :(得分:0)

好吧所以真正的罪魁祸首是Response.WriteFile在这种情况下。在我的情况下,我猜因为数据的大小非常庞大Response.WriteFile没有按预期工作。我发现一些在大文件下载的情况下,最好使用Response.TransmitFile.Left没有其他选项我改变了我的代码并使用了Response.TransmitFile和eureka!问题解决了。下载文件中没有更多重复记录。虽然原因尚不清楚,但Response.TransmitFile解决了这个问题......