2010-03-15 48 views
2

我有一個Web服務,在該服務中,我操作POST和GET方法以便於客戶端/服務器樣式體系結構中某些文件的上載/下載功能。基本上,用戶可以點擊按鈕下載特定文件,在應用程序中進行一些更改,然後點擊上傳按鈕將其發回。使用下載文件從服務器抓取文件的Webclient - 處理異常

問題我正在下載。假設用戶期望3個文件1.txt,2.txt和3.txt。服務器上不存在2.txt。

所以不得不像(服務器端)的代碼:

public class HttpHandler : IHttpHandler 
{ 

    public void ProcessRequest 
    { 
     if (context.Request.HttpMethod == "GET") 
     { 
      GoGetIt(context) 
     } 
    } 

private static void GoGetIt(HttpContext context) 
{ 
    var fileInfoOfWhereTheFileShouldBe = new FileInfo(......); 

    if (!fileInfoOfWhereTheFileShouldBe.RefreshExists()) 
    { 
      //Remove this line below 
      //throw new Exception("Oh dear the file doesn't exist"); 

      //Replace with a force return of whichever code I chose e.g. 200 
      ??... 
    } 

    ... 

所以,我有問題是,當我運行該應用程序,我用在客戶端側上的Web客戶端使用DownloadFile方法,其然後使用我得到的代碼如下:

WebException未處理:遠程服務器返回錯誤:(500)內部服務器錯誤。

(在調試過程中)如果我連接到瀏覽器並使用http://localhost:xxx/1.txt,我可以逐步瀏覽服務器端代碼並​​按預期引發異常。所以我想我想知道如何正確處理客戶端的內部服務器錯誤,以便我可以返回一些有意義的內容,如「文件不存在」。一個想法是使用圍繞WebClient.DownloadFile(address, filename)方法的嘗試,但我不確定這是否會發生唯一的錯誤,即文件不存在。

編輯:使用的HttpResponse

所以,如果我使用的HttpResponse,我能得到一些建議,如何啓動解決以下?

我從客戶端刪除異常拋出,並替換爲自定義HttpResponse?所以基本上我想我會選擇一個代碼來使用,比如說200,並強制返回代碼200,如果上面的語句。見評論。

然後在客戶端只使用If (Response.StatusCode == 200),做任何我想做的事(通知用戶文件不存在)

我沿着正確的線路是?

編輯2:

我一直在使用我的周圍文件拷貝方法嘗試捕捉嘗試,然後在catch,設置狀態代碼或狀態的描述,但這種設置狀態說明時拋出異常。 。像這樣:

context.Response.StatusDescription = ex.ToString(); 
context.Response.Status = ex.ToString(); 

ArgumentOutOfRangeException - 指定的參數超出了有效值的範圍。

回答

4

如果您正在編程IHttpHandler接口,則不應該在該代碼上引發異常。決不!

而是使用Response.StatusCodeResponse.StatusDescriptionmeaningful information返回給客戶端。

讓投擲唯一例外的系統,因爲屆時,它將真的代碼的異常。

編輯補充

回答您的編輯,我願意做這將是在服務器端沒有找到將返回一個404狀態代碼文件的情況下的方式。讓客戶處理這個問題。然而,正如你所說的你正在處理一個Web服務,所以,我只是在頭文件中添加一些額外的響應,以便更好地指定服務器端到客戶端應用程序的真實情況。

編輯補充

Response.Status是和整數。這就是爲什麼你得到ArgumentOutOfRangeException

確保Status是有效的HTTP return codes之一。

+0

是出於安全原因? IHttpHandler中的異常有什麼問題? – baron 2010-03-15 03:49:48

+0

@baron:他們不會以任何有意義的方式傳播給客戶端。 – 2010-03-15 04:07:23

+0

@Paulo Santos - 你能迴應我的編輯嗎? – baron 2010-03-16 01:53:15

0

不是拋出異常,而是將異常記錄在文本文件或事件日誌中,以便您可以準確查看發生錯誤時發生的情況。

以下是用於事件記錄http://support.microsoft.com/kb/307024的示例代碼。 用於保存文本文件

public void WriteExceptionToDisk(Exception exceptionLog) 
    { 

     string loggingname = @"c:\Exception-" + DateTime.Today.Month.ToString() 
          + "-" + DateTime.Today.Day.ToString() + "-" + 
          DateTime.Today.Year.ToString() + ".txt"; 
     // Put the exception some where in the server but 
     // make sure Read/Write permission is allowed. 
     StringBuilder message = new StringBuilder(); 
     if (exceptionLog != null) 
     { 
      message.Append("Exception Date and Time "); 
      message.AppendLine(); 
      message.Append(" "); 
      message.Append(DateTime.Today.ToLongDateString() + " at "); 
      message.Append(DateTime.Now.ToLongTimeString()); 
      message.AppendLine(); 
      message.Append("Exception Message "); 
      message.AppendLine(); message.Append(" "); 
      message.Append(exceptionLog.Message); 
      message.AppendLine(); 
      message.AppendLine("Exception Detail "); 
      message.AppendLine(); 
      message.Append(exceptionLog.StackTrace); 
      message.AppendLine(); 
     } 
     else if (message == null || exceptionLog == null) 
     { 
      message.Append("Exception is not provided or is set as null.Please pass the exception."); 
     } 

     if (File.Exists(loggingname))// If logging name exists, then append the exception message 
     { 

      File.AppendAllText(loggingname, message.ToString()); 
     } 
     else 
     { 
      // Then create the file name 
      using (StreamWriter streamwriter = File.CreateText(loggingname)) 
      { 
       streamwriter.AutoFlush = true; 
       streamwriter.Write(message.ToString()); 
       streamwriter.Close(); 
      }     
     } 
    } 
+1

-1:1)StreamWriter需要位於'using'塊中,否則如果拋出異常,資源將被泄漏。 2)通過字符串連接構建消息。 – 2010-03-15 04:09:39

+0

@約翰桑德斯。爲什麼StreamWriter應該使用block.I只是明確關閉? – wonde 2010-03-15 04:45:24

+1

因爲如果拋出異常** WHILE **正在使用'StreamWriter',那麼資源將被泄漏。通過使用'using'子句包裝它,即使發生異常,也能確保資源被正確清除。 – 2010-03-15 10:09:32