Глобально зарегистрируйте исключения из сервисов ASP.NET [ScriptService]

Вот мое предлагаемое решение, включающее некоторую простую (не идеальную) проверку входных данных. Я поместил решение внутри метода, поэтому запрос пользователя на ввод не обрабатывается

public static void calcTime(String sTimeIn, String sTimeOut) {
    final String timePattern = "[0-2][0-9]:[0-5][0-9]";

    if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
        throw new IllegalArgumentException();
    }

    String[] timeIn = sTimeIn.split(":");
    String[] timeOut = sTimeOut.split(":");

    int inMinutes = 60 * Integer.valueOf(timeIn[0]) + Integer.valueOf(timeIn[1]);
    int outMinutes = 60 * Integer.valueOf(timeOut[0]) + Integer.valueOf(timeOut[1]);

    int diff = 0;
    if (outMinutes > inMinutes) {
        diff = outMinutes - inMinutes;
    } else if (outMinutes < inMinutes) {
        diff = outMinutes + 24 * 60 - inMinutes;
    }

    System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut, diff / 60, diff % 60);
}

[117 ] Обновление
Вот решение на основе LocalTime и Duration

public static void calcTime2(String sTimeIn, String sTimeOut) {
    final String timePattern = "[0-2][0-9]:[0-5][0-9]";

    if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
        throw new IllegalArgumentException();
    }

    String[] timeIn = sTimeIn.split(":");
    String[] timeOut = sTimeOut.split(":");

    LocalTime localTimeIn = LocalTime.of(Integer.valueOf(timeIn[0]), Integer.valueOf(timeIn[1]));
    LocalTime localTimeOut = LocalTime.of(Integer.valueOf(timeOut[0]), Integer.valueOf(timeOut[1]));

    Duration duration;
    if (localTimeOut.isAfter(localTimeIn)) {
        duration = Duration.between(localTimeIn, localTimeOut);
    } else {
        Duration prevDay = Duration.ofHours(24).minusHours(localTimeIn.getHour()).minusMinutes(localTimeIn.getMinute());
        Duration nextDay = Duration.between(LocalTime.MIDNIGHT, localTimeOut);
        duration = prevDay.plus(nextDay);
    }

    System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut,
            duration.toHours(), duration.minusHours(duration.toHours()).toMinutes());     
}
13
задан Clyde 24 January 2009 в 00:30
поделиться

3 ответа

Можно использовать HTTP-модуль для получения сообщения об исключении, отслеживания стека и типа исключительной ситуации, который брошен методом веб-сервиса.

Сначала некоторый фон...

  • Если метод веб-сервиса выдает исключение, ответ HTTP имеет код состояния 500.

  • Если пользовательские ошибки будут от затем веб-сервиса, то возвратит сообщение об исключении и отслеживание стека клиенту как JSON. Например:
    {"Message":"Exception message","StackTrace":" at WebApplication.HelloService.HelloWorld() in C:\Projects\Stackoverflow Examples\WebApplication\WebApplication\HelloService.asmx.cs:line 22","ExceptionType":"System.ApplicationException"}

  • Когда пользовательские ошибки идут затем, веб-сервис возвращает сообщение по умолчанию клиенту и удаляет отслеживание стека и тип исключительной ситуации:
    {"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""}

Таким образом, то, что мы должны сделать, выделено пользовательские ошибки для веб-сервиса, и включите HTTP-модуль что:

  1. Проверки, если запрос для метода веб-сервиса
  2. Возвращаются чеки, если исключение было выдано - то есть, код состояния 500,
  3. Если 2) 1) и 2) верны, затем получают исходный JSON, который был бы отправлен клиенту и заменил бы его JSON по умолчанию

Код ниже является примером HTTP-модуля, который делает это:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;

public class ErrorHandlerModule : IHttpModule {

  public void Init(HttpApplication context) {
    context.PostRequestHandlerExecute += OnPostRequestHandlerExecute;
    context.EndRequest += OnEndRequest;
  }

  static void OnPostRequestHandlerExecute(object sender, EventArgs e) {
    HttpApplication context = (HttpApplication) sender;
    // TODO: Update with the correct check for your application
    if (context.Request.Path.StartsWith("/HelloService.asmx") 
        && context.Response.StatusCode == 500) {
      context.Response.Filter = 
        new ErrorHandlerFilter(context.Response.Filter);
      context.EndRequest += OnEndRequest;
    }
  }

  static void OnEndRequest(object sender, EventArgs e) {
    HttpApplication context = (HttpApplication) sender;
    ErrorHandlerFilter errorHandlerFilter = 
      context.Response.Filter as ErrorHandlerFilter;
    if (errorHandlerFilter == null) {
      return;
    }

    string originalContent =
      Encoding.UTF8.GetString(
        errorHandlerFilter.OriginalBytesWritten.ToArray());

    // If customErrors are Off then originalContent will contain JSON with
    // the original exception message, stack trace and exception type.

    // TODO: log the exception
  }

  public void Dispose() { }
}

Этот модуль использует следующий фильтр, чтобы переопределить содержание, отправленное клиенту и сохранить исходные байты (которые содержат сообщение об исключении, отслеживание стека и тип исключительной ситуации):

public class ErrorHandlerFilter : Stream {

  private readonly Stream _responseFilter;

  public List OriginalBytesWritten { get; private set; }

  private const string Content = 
    "{\"Message\":\"There was an error processing the request.\"" +
    ",\"StackTrace\":\"\",\"ExceptionType\":\"\"}";

  public ErrorHandlerFilter(Stream responseFilter) {
    _responseFilter = responseFilter;
    OriginalBytesWritten = new List();
  }

  public override void Flush() {
    byte[] bytes = Encoding.UTF8.GetBytes(Content);
    _responseFilter.Write(bytes, 0, bytes.Length);
    _responseFilter.Flush();
  }

  public override long Seek(long offset, SeekOrigin origin) {
    return _responseFilter.Seek(offset, origin);
  }

  public override void SetLength(long value) {
    _responseFilter.SetLength(value);
  }

  public override int Read(byte[] buffer, int offset, int count) {
    return _responseFilter.Read(buffer, offset, count);
  }

  public override void Write(byte[] buffer, int offset, int count) {
    for (int i = offset; i < offset + count; i++) {
      OriginalBytesWritten.Add(buffer[i]);
    }
  }

  public override bool CanRead {
    get { return _responseFilter.CanRead; }
  }

  public override bool CanSeek {
    get { return _responseFilter.CanSeek; }
  }

  public override bool CanWrite {
    get { return _responseFilter.CanWrite; }
  }

  public override long Length {
    get { return _responseFilter.Length; }
  }

  public override long Position {
    get { return _responseFilter.Position; }
    set { _responseFilter.Position = value; }
  }
}

Этот метод требует, чтобы пользовательские ошибки были выключены для веб-сервисов. Вы, вероятно, хотели бы сохранить пользовательские ошибки на для остальной части приложения, таким образом, веб-сервисы должны быть помещены в подкаталог. Пользовательские ошибки могут быть выключены в том каталоге только с помощью web.config, который переопределяет родительскую установку.

15
ответ дан 1 December 2019 в 23:32
поделиться

Я знаю, что это не отвечает на вопрос на - говорят, но я пошел на свои собственные поиски некоторое время назад для обнаружения этого и опустею врученный. Законченное обертывание каждого вызова веб-сервиса в попытке/выгоде и выгоды называет нашу программу регистрации ошибок. Сосет, но это работает.

1
ответ дан 1 December 2019 в 23:32
поделиться

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

Другая идея состояла бы в том, чтобы посмотреть на открытый исходный код elmah (Модули регистрации ошибок и Обработчики) для ASP.NET, который мог бы помочь, или у кого-то в том сообществе может быть идея.

-1
ответ дан 1 December 2019 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: