ファイル名が列であるGridViewを持つWebフォームがあります。 filenameをクリックすると、Open/Saveダイアログボックスがユーザに提示されます。ほとんどの場合、エラーメッセージ "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();
}
問題の原因は何ですか?
単純なResponse.WriteFile(filename)を使用していない理由はありますか? – Willem
データベースのファイルのダウンロード履歴を保存する必要があります。ダウンロードボタンのクリックイベントを挿入するだけで、ユーザーがダウンロードをキャンセルしても、行がテーブルに挿入されます。このような状況を避けるために、ファイルをパケットで送信するこのコードを実装しました。 – KhD
「保存」画面がユーザーの入力を待っている間に、ほとんどのブラウザーがファイルをダウンロードするため、クライアントが文書を保存したことを確認できません。ユーザーがキャンセルすると、ブラウザーが既に完全なファイルをtempディレクトリにダウンロードしている可能性が高くなります。 – Willem