Загрузка файла вызывает исключение - PullRequest
3 голосов
/ 25 июля 2011

У меня есть веб-форма с GridView, которая имеет имя файла в виде столбца.Если щелкнуть имя файла, пользователю открывается диалоговое окно «Открыть / сохранить».В большинстве случаев возникает исключение с сообщением об ошибке - The remote host closed the connection. The error code is 0x80072746.

Эта ошибка не видна пользователям ни в каком другом браузере, кроме Firefox.В Firefox выбранный файл визуализируется на самой странице, и через некоторое время страница выдает ошибку - соединение было сброшено.

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

Я поместил Buffer="false" в директиву страницы, но она не работает.Я попытался удалить Response.Flush() из своего кода, но безрезультатно.

Код загрузки моего файла выглядит следующим образом:

LinkButton btnTemp = (LinkButton)sender;
GridViewRow row = (GridViewRow)btnTemp.NamingContainer;
HiddenFieldFullFileName.Value = row.Cells[1].Text;

FileInfo file = new FileInfo(HiddenFieldFullFileName.Value);
if (file.Exists)
{
    string filePath="", fileName="";

    //store filepath and filename in separate variables
    string[] temp = row.Cells[1].Text.Split('\\');
    for (int j = 0; j < temp.Length; j++)
    {
        if (j < (temp.Length - 1))
            if(j==0)
              filePath = filePath + temp[j];
            else
              filePath = filePath + "\\" + temp[j];
        else
            fileName = temp[j];

    }
    FileStream myFile = new FileStream(row.Cells[1].Text, FileMode.Open,FileAccess.Read, FileShare.ReadWrite);

    //Reads file as binary values
    BinaryReader _BinaryReader = new BinaryReader(myFile);

    long startBytes = 0;
    string lastUpdateTimeStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
    string _EncodedData = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTimeStamp;

    //Clear the content of the response
    Response.Clear();
    Response.Buffer = false;
    Response.AddHeader("Accept-Ranges", "bytes");
    Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
    Response.AppendHeader("Last-Modified", lastUpdateTimeStamp);

    //Set the ContentType
    Response.ContentType = "application/octet-stream";

    //Add the file name and attachment,
    //which will force the open/cancel/save dialog to show, to the header
    Response.AddHeader("Content-Disposition", "attachment;filename=" + file.Name);

    //Add the file size into the response header
    Response.AddHeader("Content-Length", (file.Length - startBytes).ToString());
    Response.AddHeader("Connection", "Keep-Alive");

    //Set the Content Encoding type
    Response.ContentEncoding = Encoding.UTF8;

    //Send data
    _BinaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);

    //Dividing the data in 1024 bytes package
    int maxCount = (int)Math.Ceiling((file.Length - startBytes + 0.0) / 1024);

    //Download in block of 1024 bytes
    int i;
    for (i = 0; i < maxCount && Response.IsClientConnected; i++)
    {
        Response.BinaryWrite(_BinaryReader.ReadBytes(1024));
        Response.Flush();
    }

    //compare packets transferred with total number of packets
    if (i >= maxCount)
    {
        //get the IP address of user
        string ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        if (ipAddress == null)
        {
            ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
        }

        //write the download information to database table

    }


    //Close Binary reader and File stream
    _BinaryReader.Close();
    myFile.Close();
}

В чем причина проблемы?

Ответы [ 2 ]

2 голосов
/ 25 июля 2011

The remote host closed the connection. The error code is 0x80072746. - Это исключение возникает, если браузер не завершил загрузку до того, как сервер завершил соединение.

Это может быть из-за вашей странной схемы записи файла и sql после вашего Response.BinaryWrite.

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

Поэтому я настоятельно рекомендую Response.WriteFile(filename).

1 голос
/ 25 июля 2011

Я думаю, вы можете просто использовать Response.WriteFile, и вы должны использовать объект FileInfo, который вы уже создали. Код:

        LinkButton btnTemp = (LinkButton)sender;
        GridViewRow row = (GridViewRow)btnTemp.NamingContainer;
        HiddenFieldFullFileName.Value = row.Cells[1].Text;

        FileInfo file = new FileInfo(HiddenFieldFullFileName.Value);
        if (file.Exists)
        {

            string lastUpdateTimeStamp = file.LastWriteTimeUtc.ToString("r");
            string _EncodedData = HttpUtility.UrlEncode(file.Name, Encoding.UTF8) + lastUpdateTimeStamp;

            //Clear the content of the response
            Response.Clear(); 
            Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
            Response.AppendHeader("Last-Modified", lastUpdateTimeStamp);

            //Set the ContentType
            Response.ContentType = "application/octet-stream"; 

            //Add the file name and attachment,
            //which will force the open/cancel/save dialog to show, to the header
            Response.AddHeader("Content-Disposition", "attachment;filename=" + file.Name); 

            //Send data
            Response.WriteFile(file.FullName);
            Response.End();
        }

Если вы знаете конкретный тип контента, тогда вместо «application / octet-stream» вы можете изменить его на mimetype вашего файла (см. здесь для примеров)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...