熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

Asp.net直接保存文件到客戶端

2013-11-13 09:54:27  來源: .NET編程 

  在我們的系統的編寫過程中應該有很多的時候需要客戶下載文件我第一次的做法(應該也是大部分人的做法吧?)是:


      HttpResponse response = HttpContextCurrentResponse;
   string js = <script language=javascript>windowopen({});</script>;
   js = stringFormat(js url);
   responseWrite(js);

  但是有個問題了就是會被廣告攔截軟件直接攔截掉另我非常的頭痛於是尋找更好的解決方法看了用ResponseBinaryWrite寫文件流一文之後覺得確實可以如此修改代碼如下: 
   

     /**//**//**//// <summary>
   /**//// 下載文件
   /**//// </summary>
   /**//// <param name=filename>文件物理地址</param>
  
  protected void DownloadFile(string filename)
   {
   string saveFileName = testxls;
   int intStart = filenameLastIndexOf(\)+;
   saveFileName = filenameSubstring(intStartfilenameLengthintStart);
   FileStream MyFileStream;
   long FileSize;
  
   MyFileStream = new FileStream(filenameFileModeOpen);
   FileSize = MyFileStreamLength;
  
   byte[] Buffer = new byte[(int)FileSize];
   MyFileStreamRead(Buffer (int)FileSize);
   MyFileStreamClose();
  
   ResponseAddHeader(ContentDisposition attachment;filename=+saveFileName);
   ResponseContentEncoding = SystemTextEncodingGetEncoding(GB);
   ResponseContentType = application/vndmsexcel;
  
   ResponseBinaryWrite(Buffer);
   ResponseFlush();
   ResponseClose();
   ResponseEnd();
  
   }

  但是有個嚴重的問題就是文件格式這樣只是將流輸出且無法正確識別格式還好能人層出不窮 柚子Nan 提出了能否不考慮文件的類型直接把文件顯示到浏覽器(Response) 的想法正好切中我的要害所在於是急忙研究了柚子Nan的想法修改出最後代碼

      /**//**//**//// <summary>
   /**//// 下載文件
   /**//// </summary>
   /**//// <param name=filename>文件物理地址</param>
   protected void DownloadFile(string filename)
   {
   string saveFileName = testxls;
   int intStart = filenameLastIndexOf(\)+;
   saveFileName = filenameSubstring(intStartfilenameLengthintStart);
  
   ResponseClear();
   ResponseCharset = utf;
   ResponseBuffer= true;
   thisEnableViewState = false;
   ResponseContentEncoding = SystemTextEncodingUTF;
  
   ResponseAppendHeader(ContentDispositionattachment;filename= + saveFileName);
   ResponseWriteFile(filename);
   ResponseFlush();
   ResponseClose();
  
   ResponseEnd();
   }

  使用昨天直接保存文件到客戶端 中的方法經過我的反復測試各式文檔都運行完全正常於是昨晚修改了現有代碼修改了下載方法以解決一直困擾自己的窗口攔截問題
  
    早上本來還沾沾自喜這下再也不用老跟客戶解釋為什麼窗口會沒掉了可惜啊人算不如天算
  
    早上客戶就反映下載的文件全是亂碼立馬在本機進行測試沒問題再同事的機器上試驗同樣沒問題
  
    那應該是客戶端的問題才是只好讓客戶NetMeeting演示一下她的操作過程下載〉保存〉打開這麼簡單的流程不會做錯吧?
  
    正在郁悶之際突然腦光一閃終於發現不一樣的地方立馬試驗果然如此!
  
    到底有什麼區別呢?請看操作圖:
  客人操作圖
  我的操作圖
  各位應該看出不同之處了吧?還看不出來?
  這件事情的罪魁禍首就是:
  
  
  
    解決方法:使用lovecherry 的如何從注冊表讀取文件的ContentType 一文的方法

       修正代碼:
   /**//// <summary>
   /// 下載文件
   /// </summary>
   /// <param name=filename>文件物理地址</param>
   protected void DownloadFile(string filename)
   {
  
   string saveFileName = testxls;
   int intStart = filenameLastIndexOf(\\)+;
   saveFileName = filenameSubstring(intStartfilenameLengthintStart);
  
   SystemIOFileInfo fi=new SystemIOFileInfo(filename);
   string fileextname=fiExtension;
   string DEFAULT_CONTENT_TYPE = application/unknown;
   RegistryKey regkeyfileextkey;
   string filecontenttype;
   try
   {
   regkey=RegistryClassesRoot;
   fileextkey=regkeyOpenSubKey(fileextname);
   filecontenttype=fileextkeyGetValue(Content TypeDEFAULT_CONTENT_TYPE)ToString();
   }
   catch
   {
   filecontenttype=DEFAULT_CONTENT_TYPE;
   }
  
  
   ResponseClear();
   ResponseCharset = utf;
   ResponseBuffer= true;
   thisEnableViewState = false;
   ResponseContentEncoding = SystemTextEncodingUTF;
  
   ResponseAppendHeader(ContentDispositionattachment;filename= + saveFileName);
   ResponseContentType=filecontenttype;
  
   ResponseWriteFile(filename);
   ResponseFlush();
   ResponseClose();
  
   ResponseEnd();
   }
    最後得出結論:要實現柚子Nan提出的能否不考慮文件的類型直接把文件顯示到浏覽器(Response)有一種方法讓客戶端都不要隱藏已知的擴展名但是這種方法是無法適應大部分電腦使用者的(一般只有比較熟悉電腦的人才會這樣做吧?)

  bbs 看中的方法還沒有試用不知道有沒有作用

      Private Sub Page_Load(ByVal sender As SystemObject ByVal e As SystemEventArgs) _
   Handles MyBaseLoad
   在此處放置初始化頁的用戶代碼
   定義是否是 SQL Server 數據庫這裡為False
   Dim blnIsSQLServer As SystemBoolean = False
   Dim strSQL As String
   Dim objDataset As New DataSet()
   Dim objConn As Object
   Dim strCnn As String
  
   If blnIsSQLServer Then
   strCnn = User ID=sa;Initial Catalog=Northwind;Data Source=\NetSDK;
   objConn = New SystemDataSqlClientSqlConnection(strCnn)
   objConnOpen()
   Dim objAdapter As New SystemDataSqlClientSqlDataAdapter()
   strSQL = Select * from customers where country=USA
   objAdapterSelectCommand = New SystemDataSqlClientSqlCommand(strSQL objConn)
   objAdapterFill(objDataset)
   Else
   strCnn = Provider=MicrosoftJetOLEDB;Data Source= + ServerMapPath(Testmdb)
   objConn = New SystemDataOleDbOleDbConnection(strCnn)
   objConnOpen()
   Dim objAdapter As New SystemDataOleDbOleDbDataAdapter()
   strSQL = Select Top Title From Document
   objAdapterSelectCommand = New SystemDataOleDbOleDbCommand(strSQL objConn)
   objAdapterFill(objDataset)
   End If
   Dim oView As New DataView(objDatasetTables())
   DataGridDataSource = oView
   DataGridDataBind()
   objConnClose()
   objConnDispose()
   objConn = Nothing
   If RequestQueryString(bExcel) = Then
   ResponseContentType = application/vndmsexcel
   從ContentType header中去除charset設置
   ResponseCharset =
  
   關閉 ViewState
   MeEnableViewState = False
   Dim tw As New SystemIOStringWriter()
   Dim hw As New SystemWebUIHtmlTextWriter(tw)
   獲取control的HTML
   DataGridRenderControl(hw)
   把HTML寫回浏覽器
   ResponseWrite(twToString())
   ResponseEnd()
   End If
   End Sub


From:http://tw.wingwit.com/Article/program/net/201311/11936.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.