Веб-клиент использует загрузочный файл для захвата файла с сервера - обработка исключений - PullRequest
2 голосов
/ 15 марта 2010

У меня есть веб-сервис, в котором я манипулирую методами POST и GET, чтобы упростить загрузку / выгрузку некоторых файлов в архитектуре стиля клиент / сервер. Обычно пользователь может нажать кнопку, чтобы загрузить определенный файл, внести некоторые изменения в приложение, а затем нажать кнопку загрузки, чтобы отправить его обратно.

Проблема с загрузкой. Скажем, пользователь ожидает 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
          ??...
     }

    ...

Итак, у меня проблема в том, что когда я запускаю приложение и использую WebClient на стороне клиента, чтобы использовать метод DownloadFile, который затем использует код, который у меня есть выше, я получаю:

WebException не обработано: удаленный сервер возвратил ошибку: (500) Внутренняя ошибка сервера.

(во время отладки) Если я присоединяюсь к браузеру и использую http://localhost:xxx/1.txt, я могу просмотреть код на стороне сервера и выдать исключение, как предполагалось. Поэтому я думаю, мне интересно, как я могу правильно обработать внутреннюю ошибку сервера на стороне клиента, чтобы я мог вернуть что-то осмысленное, например «Файл не существует». Одна мысль состояла в том, чтобы использовать попытку catch в методе WebClient.DownloadFile(address, filename), но я не уверен, что это единственная ошибка, которая произойдет, то есть файл не существует.

edit: следуя решению, используя HttpResponse

Так что, если бы я использовал HttpResponse, мог бы я получить несколько советов о том, как начать?

Я удаляю исключение с клиентской стороны и заменяю его собственным HttpResponse? В общем, я думаю, я бы выбрал код для использования, скажем, 200, и принудительный код возврата 200 в этом операторе if выше. Смотрите комментарий.

Тогда на стороне клиента просто используйте If (Response.StatusCode == 200) и делайте все, что я хочу сделать (сообщите, что пользовательский файл не существует)

Я на правильном пути?

редактировать 2:

Я пытался использовать попытку catch для моих методов копирования файлов, а затем в catch, устанавливая код состояния или описание статуса, но это выдает исключения при настройке описания статуса .. например:

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

ArgumentOutOfRangeException - указанный аргумент находится вне диапазона допустимых значений.

Ответы [ 2 ]

4 голосов
/ 15 марта 2010

Если вы программируете интерфейс IHttpHandler, вы не должны создавать исключения для этого кода. Никогда! * * 1002

Вместо этого используйте Response.StatusCode и Response.StatusDescription для возврата значимой информации клиенту.

Пусть выбрасывающее исключение только для системы, потому что тогда ДЕЙСТВИТЕЛЬНО будет исключением из ВАШ кода.

Отредактировано для добавления

Отвечая на ваши изменения, я бы поступил так, как если бы файл, не найденный на стороне сервера, возвратил бы 404 код состояния. И пусть клиент справится с этим.

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

Отредактировано для добавления

Response.Status является целым числом. Вот почему вы получаете ArgumentOutOfRangeException.

Убедитесь, что Status является одним из действительных кодов возврата HTTP .

0 голосов
/ 15 марта 2010

Вместо того, чтобы выдавать исключение, зарегистрируйте исключение в текстовом файле или журнале событий, чтобы вы могли точно видеть, что произошло при возникновении ошибки.

Вот пример кода для регистрации событий 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();
            }                 
        }
    }
...