c# – 如果抛出Exception,.Net Web API偶尔会返回没有响应

c# – 如果抛出Exception,.Net Web API偶尔会返回没有响应,第1张

概述首先是一些背景知识. 我在Visual Studio 2017社区中使用.Net Framework 4.6.1,Microsoft.AspNet.WebApi 5.2.4. 我的ApiController的实现端点会抛出预期的异常,例如,如果不满足某些要求.我添加了全局ExceptionFilterAttribute和ExceptionHandler来处理这些异常并返回正确的响应. 异常是一种继 首先是一些背景知识.
我在Visual Studio 2017社区中使用.Net Framework 4.6.1,Microsoft.AspNet.WebAPI 5.2.4.

我的APIController的实现端点会抛出预期的异常,例如,如果不满足某些要求.我添加了全局ExceptionFilterattribute和ExceptionHandler来处理这些异常并返回正确的响应.
异常是一种继承System.Exception的类型.
这只是偶尔按预期工作.每隔一秒或三分之一或有时第五(没有实际模式)请求API服务器根本不返回任何响应,例如例如Postman说:“无法得到任何回应”.
为了测试这个,我使用了具有相同输入的相同端点.

以下是我为了更好地了解问题所做的一些事情:
我向Global.asax添加了异常日志记录(以捕获First Chance Exceptions)
我订阅了Global.asax Application_Error事件
我查看了IIS日志

没有人让我更接近这个问题.异常被捕获并记录在Global.asax中,就像预期的那样,但是没有其他错误或异常可以为我的问题提供更多信息.

这是我的代码:
我简化了APIController的功能并删除了业务逻辑.

[Route("test")][httpGet]public IhttpActionResult Gettest(){    throw new ObjectAlreadyExistsException("test");    return ResponseFactory.CreateOkResponse(null);}public class ExceptionFilter : ExceptionFilterattribute{    public overrIDe voID OnException(httpActionExecutedContext context)    {        if (context.Exception is ObjectAlreadyExistsException)        {            context.Response = ResponseFactory.CreateErrorResponseMessage(context.Exception.Message,new Error("OBJECT_ALREADY_EXISTS_ERROR",context.Exception.Message));        }        else if (context.Exception is ObjectNotFoundException)        {            context.Response = ResponseFactory.CreateErrorResponseMessage(context.Exception.Message,new Error("OBJECT_NOT_FOUND_ERROR",context.Exception.Message));        }        base.OnException(context);    }}public class GlobalExceptionHandler : ExceptionHandler{    private static Readonly ILogger Log = new LoggerConfiguration()            .Writeto.file(new CompactJsonFormatter(),Path.Combine(@PropertIEs.Settings.Default.LOG_DIRECTORY,@"error.Json"),rollOnfileSizelimit: true,retainedfileCountlimit: 5,shared: true)            .Enrich.WithWebAPIControllername()            .Enrich.WithWebAPIActionname()            .Enrich.WithWebAPIRouteTemplate()            .Enrich.WithWebAPIRouteData()            .Enrich.With(new AuthTokenEnricher())            .CreateLogger();    public overrIDe voID Handle(ExceptionHandlerContext context)    {        if (context != null && context.Exception != null)        {            Log.Error("Unexpected Internal Server Error {Exception}",context.Exception);        }        context.Result = ResponseFactory.CreateErrorResponse(httpStatusCode.InternalServerError,"Unexpected Internal Server Error",new Error("INTERNAL_SERVER_ERROR","This request Failed because of an unexpected server error."));    }}public static class WebAPIConfig{    public static voID Register(httpConfiguration config)    {        //Exception filters        config.Filters.Add(new ExceptionFilter());        config.Services.Replace(typeof(IExceptionHandler),new GlobalExceptionHandler());        // Web API routes        config.MaphttpAttributeRoutes();    }}public class ObjectAlreadyExistsException : Exception{    public ObjectAlreadyExistsException(string message) : base(message)    {    }    public ObjectAlreadyExistsException(string message,Exception inner) : base(message,inner)    {    }}

现在我提出了一个解决方法,看起来像这样:

[Route("test")][httpGet]public IhttpActionResult Gettest(){    try    {        throw new ObjectAlreadyExistsException("test");    }    catch (Exception ex)    {        return CustomExceptionHandler.Handle(ex);    }}public class CustomExceptionHandler{    private static Readonly ILogger Log = new LoggerConfiguration()            .Writeto.file(new CompactJsonFormatter(),shared: true)            .Enrich.WithWebAPIControllername()            .Enrich.WithWebAPIActionname()            .Enrich.WithWebAPIRouteTemplate()            .Enrich.WithWebAPIRouteData()            .Enrich.With(new AuthTokenEnricher())            .CreateLogger();    public static IhttpActionResult Handle(Exception ex)    {        IhttpActionResult result = null;        if (ex != null)        {            if (ex is ObjectAlreadyExistsException)            {                result = ResponseFactory.CreateErrorResponse(ex.Message,ex.Message));            }            else if (ex is ObjectNotFoundException)            {                result = ResponseFactory.CreateErrorResponse(ex.Message,ex.Message));            }        }        if (result == null)        {            if (ex != null)            {                Log.Error("Unexpected Internal Server Error {Exception}",ex);            }            result = ResponseFactory.CreateErrorResponse(httpStatusCode.InternalServerError,"This request Failed because of an unexpected server error."));        }        return result;    }}

我将不胜感激任何想法如何调试此或任何建议来解决它.

解决方法 你可以尝试从IhttpActionResult继承并使用它作为从GlobalExceptionHandler返回异常

private class ErrorMessageResult : IhttpActionResult    {        private Readonly httpResponseMessage _httpResponseMessage;        private httpRequestMessage _request;        public ErrorMessageResult(httpRequestMessage request,httpResponseMessage httpResponseMessage)        {            _request = request;            _httpResponseMessage = httpResponseMessage;        }        public Task<httpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)        {            return Task.Fromresult(_httpResponseMessage);        }    }

并称之为,

public overrIDe voID Handle(ExceptionHandlerContext context){    var result = new httpResponseMessage(httpStatusCode.InternalServerError)    {        Content = new StringContent("Internal Server Error Occurred"),ReasonPhrase = "Exception"    };    context.Result = new ErrorMessageResult(context.Request,result);}

来自GlobalExceptionHandler:ExceptionHandler

总结

以上是内存溢出为你收集整理的c# – 如果抛出Exception,.Net Web API偶尔会返回没有响应全部内容,希望文章能够帮你解决c# – 如果抛出Exception,.Net Web API偶尔会返回没有响应所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1233299.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存