it-swarm.com.de

Benötigen Sie ein vollständiges Beispiel, um nicht behandelte Ausnahmen mit "ExceptionHandler" in ASP.NET Web Api zu behandeln?

Ich hatte diesen Link überprüft http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling ..__ In diesem Link haben sie so erwähnt

class OopsExceptionHandler : ExceptionHandler
{
    public override void HandleCore(ExceptionHandlerContext context)
    {
        context.Result = new TextPlainErrorResult
        {
            Request = context.ExceptionContext.Request,
            Content = "Oops! Sorry! Something went wrong." +
                      "Please contact [email protected] so we can try to fix it."
        };
    }

    private class TextPlainErrorResult : IHttpActionResult
    {
        public HttpRequestMessage Request { get; set; }

        public string Content { get; set; }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response = 
                             new HttpResponseMessage(HttpStatusCode.InternalServerError);
            response.Content = new StringContent(Content);
            response.RequestMessage = Request;
            return Task.FromResult(response);
        }
    }
}

Ich weiß nicht, wie ich diese Klasse in meinen Web-API-Aktionen aufrufen kann. So kann mir jeder das komplette Beispiel mit dieser ExceptionHandler geben.

28
user3331492

In Ihrer WebApi-Konfiguration müssen Sie die Zeile hinzufügen:

config.Services.Replace(typeof (IExceptionHandler), new OopsExceptionHandler());

Stellen Sie außerdem sicher, dass Sie die Basis-ExceptionHandler-Klasse erstellt haben, die IExceptionHandler implementiert:

public class ExceptionHandler : IExceptionHandler
{
    public virtual Task HandleAsync(ExceptionHandlerContext context, 
                                    CancellationToken cancellationToken)
    {
        if (!ShouldHandle(context))
        {
            return Task.FromResult(0);
        }

        return HandleAsyncCore(context, cancellationToken);
    }

    public virtual Task HandleAsyncCore(ExceptionHandlerContext context, 
                                       CancellationToken cancellationToken)
    {
        HandleCore(context);
        return Task.FromResult(0);
    }

    public virtual void HandleCore(ExceptionHandlerContext context)
    {
    }

    public virtual bool ShouldHandle(ExceptionHandlerContext context)
    {
        return context.CatchBlock.IsTopLevel;
    }
} 

Beachten Sie, dass hier nur Ausnahmen behandelt werden, die nicht an anderer Stelle behandelt werden (z. B. durch Ausnahmefilter).

26
Jon Susiak

Sie müssen den IExceptionHandler-Mechanismus auf niedriger Ebene nicht selbst implementieren.

Stattdessen können Sie einfach von ExceptionHandler erben und die Handle -Methode überschreiben.

public class MyExceptionHandler: ExceptionHandler
{
  public override void Handle(ExceptionHandlerContext context)
  {
    //TODO: Do what you need to do
    base.Handle(context);
  }
}

ExceptionHandler implementiert IExceptionHandler und verwaltet grundlegende Kernmechanismen (wie async und diese Ausnahme sollte behandelt werden oder nicht).

Verwenden Sie Ihren Ausnahmebehandler wie folgt:

config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());

Quelle

Diese Seite erläutert, wie IExceptionHandler implementiert wird. Es gibt jedoch einige Tippfehler und der Code spiegelt nicht die neueste Version von WebApi wider.

Es gibt keine Dokumentation zum System.Web.Http.ExceptionHandling-Namespace (etwas zu NuDoq ).

So.. verwenden eines .NET Assembly-Dekompilierers Als ich den Quellcode auf GitHub sah, sah ich die ExceptionHandler-Klasse, die IExceptionHandler implementiert und einige virtuelle Methoden hat. 

ExceptionHandler sieht so aus:

namespace System.Web.Http.ExceptionHandling
{
    /// <summary>Represents an unhandled exception handler.</summary>
    public abstract class ExceptionHandler: IExceptionHandler
    {
        /// <returns>Returns <see cref="T:System.Threading.Tasks.Task" />.</returns>
        Task IExceptionHandler.HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            ExceptionContext arg_14_0 = context.ExceptionContext;
            if (!this.ShouldHandle(context))
            {
                return TaskHelpers.Completed();
            }
            return this.HandleAsync(context, cancellationToken);
        }

        /// <summary>When overridden in a derived class, handles the exception asynchronously.</summary>
        /// <returns>A task representing the asynchronous exception handling operation.</returns>
        /// <param name="context">The exception handler context.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        public virtual Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
        {
            this.Handle(context);
            return TaskHelpers.Completed();
        }

        /// <summary>When overridden in a derived class, handles the exception synchronously.</summary>
        /// <param name="context">The exception handler context.</param>
        public virtual void Handle(ExceptionHandlerContext context)
        {
        }

        /// <summary>Determines whether the exception should be handled.</summary>
        /// <returns>true if the exception should be handled; otherwise, false.</returns>
        /// <param name="context">The exception handler context.</param>
        public virtual bool ShouldHandle(ExceptionHandlerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            ExceptionContext exceptionContext = context.ExceptionContext;
            ExceptionContextCatchBlock catchBlock = exceptionContext.CatchBlock;
            return catchBlock.IsTopLevel;
        }
    }
}

Sie können deutlich sehen, dass ShouldHandle mit ExceptionContextCatchBlock.IsTopLevel implementiert ist und dass HandleAsyncHandle aufruft.

Ich hoffe, dass dies hilft, bis die vollständige Dokumentation angezeigt wird.

82
Yves M.

Laut Jon Susiaks Antwort müssen Sie Folgendes verwenden:

config.Services.Replace(typeof (IExceptionHandler), new OopsExceptionHandler());

Beachten Sie den Aufruf Replace, nicht Add. Der Grund dafür ist der Artikel unter diesem Link:

Globale Fehlerbehandlung in ASP.NET Web API 2

Lösungsüberblick

Wir bieten zwei neue vom Benutzer ersetzbare Dienste an, IExceptionLogger und IExceptionHandler, um nicht behandelte Ausnahmen zu protokollieren und zu behandeln. 

Das Die Dienste sind sehr ähnlich, mit zwei Hauptunterschieden: 

Wir unterstützen die Registrierung mehrerer Ausnahmelogger, aber nur ein einziges Ausnahmebehandler

Da standardmäßig bereits ein Handler registriert ist, können Sie keinen weiteren hinzufügen.

public DefaultServices(HttpConfiguration configuration)
    {
      if (configuration == null)
        throw System.Web.Http.Error.ArgumentNull("configuration");
      this._configuration = configuration;
      this.SetSingle<IActionValueBinder>((IActionValueBinder) new DefaultActionValueBinder());
      this.SetSingle<IApiExplorer>((IApiExplorer) new ApiExplorer(configuration));
      this.SetSingle<IAssembliesResolver>((IAssembliesResolver) new DefaultAssembliesResolver());
      this.SetSingle<IBodyModelValidator>((IBodyModelValidator) new DefaultBodyModelValidator());
      this.SetSingle<IContentNegotiator>((IContentNegotiator) new DefaultContentNegotiator());
      this.SetSingle<IDocumentationProvider>((IDocumentationProvider) null);
      this.SetMultiple<IFilterProvider>((IFilterProvider) new ConfigurationFilterProvider(), (IFilterProvider) new ActionDescriptorFilterProvider());
      this.SetSingle<IHostBufferPolicySelector>((IHostBufferPolicySelector) null);
      this.SetSingle<IHttpActionInvoker>((IHttpActionInvoker) new ApiControllerActionInvoker());
      this.SetSingle<IHttpActionSelector>((IHttpActionSelector) new ApiControllerActionSelector());
      this.SetSingle<IHttpControllerActivator>((IHttpControllerActivator) new DefaultHttpControllerActivator());
      this.SetSingle<IHttpControllerSelector>((IHttpControllerSelector) new DefaultHttpControllerSelector(configuration));
      this.SetSingle<IHttpControllerTypeResolver>((IHttpControllerTypeResolver) new DefaultHttpControllerTypeResolver());
      this.SetSingle<ITraceManager>((ITraceManager) new TraceManager());
      this.SetSingle<ITraceWriter>((ITraceWriter) null);
      this.SetMultiple<ModelBinderProvider>((ModelBinderProvider) new TypeConverterModelBinderProvider(), (ModelBinderProvider) new TypeMatchModelBinderProvider(), (ModelBinderProvider) new KeyValuePairModelBinderProvider(), (ModelBinderProvider) new ComplexModelDtoModelBinderProvider(), (ModelBinderProvider) new ArrayModelBinderProvider(), (ModelBinderProvider) new DictionaryModelBinderProvider(), (ModelBinderProvider) new CollectionModelBinderProvider(), (ModelBinderProvider) new MutableObjectModelBinderProvider());
      this.SetSingle<ModelMetadataProvider>((ModelMetadataProvider) new DataAnnotationsModelMetadataProvider());
      this.SetMultiple<ModelValidatorProvider>((ModelValidatorProvider) new DataAnnotationsModelValidatorProvider(), (ModelValidatorProvider) new DataMemberModelValidatorProvider());
      this.SetMultiple<ValueProviderFactory>((ValueProviderFactory) new QueryStringValueProviderFactory(), (ValueProviderFactory) new RouteDataValueProviderFactory());
      this.SetSingle<IModelValidatorCache>((IModelValidatorCache) new ModelValidatorCache(new Lazy<IEnumerable<ModelValidatorProvider>>((Func<IEnumerable<ModelValidatorProvider>>) (() => ServicesExtensions.GetModelValidatorProviders((ServicesContainer) this)))));

      this.SetSingle<IExceptionHandler>((IExceptionHandler) new DefaultExceptionHandler());

      this.SetMultiple<IExceptionLogger>();
      this._serviceTypesSingle = new HashSet<Type>((IEnumerable<Type>) this._defaultServicesSingle.Keys);
      this._serviceTypesMulti = new HashSet<Type>((IEnumerable<Type>) this._defaultServicesMulti.Keys);
      this.ResetCache();
    }
4
rism

Sie können einen Blick auf das folgende Beispiel aus dem Web API-Team werfen:

http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/Elmah/ReadMe.txt

0
Kiran Challa