Response.WriteFile пишет содержимое дважды

Вот мой код..

 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 из местоположения. Но удивительно, что содержимое записывается дважды или несколько раз в файл, который я загружаю, хотя на самом деле это не так с файлом на сервере. Я пишу мой код в с #. Приведенный выше фрагмент кода отлично работает на локальном компьютере, но проблема заключается в производственном сервере.

Вот мой полный метод

 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 ответа

Решение

Хорошо, так что настоящим виновником в этом случае был Response.WriteFile. В моем случае, я думаю, поскольку размер данных был довольно велик, Response.WriteFile не работал должным образом. Я нашел кое-где, что в случае загрузки больших файлов, лучше всего использовать Response.TransmitFile.Left без каких-либо других вариантов, я изменил свой код и использовал Response.TransmitFile и eureka! проблема была решена. В загруженном файле больше нет повторяющихся записей. Хотя причина до сих пор неизвестна, Response.TransmitFile решил проблему.....

Вы можете проверить, для чего предназначены следующие строки:

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();
        }

Там явно что-то странное происходит. Вы сказали, что он работает в dev, но не в Prod. Используете ли вы одну и ту же конфигурацию сервера в обеих средах (т.е. используете ли вы 1 сервер в dev, а 2 в prod?)

У вас потенциально есть 3 шага, если я понял ваш код...

  • Создать отчет из SQL и записать его в файл
  • Если файл хранится на другом сервере, загрузите его на веб-сервер
  • Служить

Итак, в более сложном сценарии (который я предполагаю, что производство), На каком этапе процесса вы начинаете видеть двойные записи? На сервере отчет генерируется, на копии веб-серверов или только на клиенте после получения его с веб-сервера?

Я не вижу никакой причины, по которой ваш код для передачи файла клиенту будет дублировать данные, поэтому я могу только предполагать, что это происходит раньше, в какой-то момент.

Было бы полезно, если бы вы могли использовать Firebug/Fiddler/??? опубликовать точное содержание передачи с веб-сервера клиенту

(Кстати, вы можете посмотреть на System.IO.Path класс для манипулирования путями, он делает ваш код более читабельным и надежным - больше не нужно беспокоиться о конечных слешах!)

Другие вопросы по тегам