2

クライアント/サーバー スタイルのアーキテクチャで一部のファイルのアップロード/ダウンロード機能を容易にするために、POST メソッドと GET メソッドを操作する Web サービスがあります。基本的に、ユーザーはボタンをクリックして特定のファイルをダウンロードし、アプリでいくつかの変更を加えてから、アップロード ボタンをクリックして送り返すことができます。

私が抱えている問題はダウンロードにあります。ユーザーが 1.txt、2.txt、3.txt の 3 つのファイルを期待しているとします。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
          ??...
     }

    ...

したがって、私が抱えている問題は、アプリケーションを実行し、クライアント側で WebClient を使用して DownloadFile メソッドを使用し、上記のコードを使用すると、次のようになることです。

WebException が処理されませんでした: リモート サーバーがエラーを返しました: (500) 内部サーバー エラー。

(デバッグ中)ブラウザにアタッチして使用するとhttp://localhost:xxx/1.txt、サーバー側のコードをステップ実行して、意図したとおりに例外をスローできます。したがって、クライアント側で内部サーバーエラーを適切に処理して、「ファイルが存在しません」などの意味のあるものを返すことができるかどうか疑問に思っていると思います。メソッドの周りに try catch を使用することも考えられましたが、WebClient.DownloadFile(address, filename)発生する唯一のエラー、つまりファイルが存在しないかどうかはわかりません。

編集:HttpResponseを使用したソリューションに従う

HttpResponse を使用する場合、開始方法についていくつか提案をいただけないでしょうか?

クライアント側から例外スローを削除し、カスタム HttpResponse に置き換えますか? したがって、基本的には、使用するコード、たとえば 200 を選択し、上記の if ステートメントでリターン コード 200 を強制すると思います。コメントを参照してください。

次に、クライアント側でIf (Response.StatusCode == 200)、やりたいことを何でも使用して実行します(ユーザーファイルが存在しないことを通知します)

私は正しい線に沿っていますか?

編集2:

ファイルコピーメソッドの周りでtry catchを使用してから、キャッチでステータスコードまたはステータスの説明を設定しようとしましたが、ステータスの説明を設定すると例外がスローされます..次のように:

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

ArgumentOutOfRangeException - 指定された引数が有効な値の範囲外でした。

4

2 に答える 2

4

インターフェイスをプログラミングしている場合はIHttpHandler、そのコードで例外をスローしないでください。一度もない!

代わりにResponse.StatusCodeandを使用して、意味のある情報をクライアントResponse.StatusDescriptionに返します。

システムにのみ例外をスローさせてください。そうすると、それは本当にあなたのコードの例外になるからです。

編集して追加

404あなたの編集に答えると、サーバー側で見つからないファイルがステータスコードを返す場合に私が行う方法です。そして、クライアントにこれを処理させます。

ただし、あなたが言ったように、Web サービスを扱っているので、サーバー側で実際に何が起こっているかをクライアント アプリケーションに正確に指定するために、ヘッダーに追加の応答を追加するだけです。

編集して追加

Response.Statusと整数です。それがあなたが得ている理由ですArgumentOutOfRangeException

Status が有効なHTTP リターン コードの 1 つであることを確認します。

于 2010-03-15T03:30:26.270 に答える
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();
            }                 
        }
    }
于 2010-03-15T04:04:49.540 に答える