15

Api arayana dost bir hata iletisi döndürmek için işlenmeyen tüm özel durumları işleyen web api 2.0'da genel bir ExceptionHandler var. Ayrıca, web api'mde çok özel bir istisna uygulayan ve belirli bir yanıt veren global bir ExceptionFilter var. ExceptionFilter bir eklenti tarafından web api'ye dinamik olarak eklenir, böylece ExceptionHandler'ımda ne yaptığımı yapamıyorum.ASP.NET Web Api 2.0'da öncelik, ExceptionFilter veya ExceptionHandler hangisi alır?

Hem ExceptionHandler hem de ExceptionFilter'ın global olarak kayıtlı olup olmadığını merak ediyorum; hangisi öncelikli olacak ve ilk olarak çalıştırılacak? Şu anda ExceptionFilter'in ExceptionHandler'dan önce yürütüldüğünü görebiliyorum. Ayrıca ExceptionFilter'imde bir özel durum oluşturduğumda, ExceptionHandler'ın yürütülmediğini görebiliyorum.

o varsaymak güvende olacak:

  1. ExceptionFilters ExceptionHandlers önce yürütülür.

  2. ExceptionFilter bir yanıt oluşturursa, ExceptionHandler çalıştırılmaz.

cevap

25

Sorunun cevabını bulmak için System.Web.Http aracılığıyla hata ayıklamak zorunda kaldım. Yani cevap:

  1. ExceptionFilters ExceptionHandlers ExceptionFilter ExceptionHandler idam edilmeyeceği bir yanıt oluşturursa

  2. önce çalıştırılacaktır varsaymak güvenlidir.

Bu neden böyledir: Bir ExceptionFilter küresel veya denetleyici eylem için yürütülecek kayıtlı olduğunda

, tüm API Kontrolörler devralan hangi ApiController taban sınıfı bir ExceptionFilterResult sonucu kaydırılır ve ExecuteAsync yöntemini çağır.

try 
{ 
    return await _innerResult.ExecuteAsync(cancellationToken); 
} 
catch (Exception e) 
{ 
    exceptionInfo = ExceptionDispatchInfo.Capture(e); 
} 

// This code path only runs if the task is faulted with an exception 
Exception exception = exceptionInfo.SourceException; 
Debug.Assert(exception != null); 

bool isCancellationException = exception is OperationCanceledException; 

ExceptionContext exceptionContext = new ExceptionContext(
    exception, 
    ExceptionCatchBlocks.IExceptionFilter, 
    _context); 

if (!isCancellationException) 
{ 
    // We don't log cancellation exceptions because it doesn't represent an error. 
    await _exceptionLogger.LogAsync(exceptionContext, cancellationToken); 
} 

HttpActionExecutedContext executedContext = new HttpActionExecutedContext(_context, exception); 

// Note: exception filters need to be scheduled in the reverse order so that 
// the more specific filter (e.g. Action) executes before the less specific ones (e.g. Global) 
for (int i = _filters.Length - 1; i >= 0; i--) 
{ 
    IExceptionFilter exceptionFilter = _filters[i]; 
    await exceptionFilter.ExecuteExceptionFilterAsync(executedContext, cancellationToken); 
} 

if (executedContext.Response == null && !isCancellationException) 
{ 
    // We don't log cancellation exceptions because it doesn't represent an error. 
    executedContext.Response = await _exceptionHandler.HandleAsync(exceptionContext, cancellationToken); 
} 

Ardından tüm ExceptionFilters vardır ExceptionLogger ilk yürütülür görebilirsiniz:

if (exceptionFilters.Length > 0) 
{ 
    IExceptionLogger exceptionLogger = ExceptionServices.GetLogger(controllerServices); 
    IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(controllerServices); 
    result = new ExceptionFilterResult(ActionContext, exceptionFilters, exceptionLogger, exceptionHandler, 
     result); 
} 

return result.ExecuteAsync(cancellationToken); 

ExceptionFilterResult.ExecuteAsync yöntemine baktığımızda: Bu bunu yapar ApiController içinde koddur yürütülür ve eğer execContext.Response == null ise, ExceptionHandler çalıştırılır.

Umarım bu yararlıdır!