Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WebAPI筛选器的ActionExecuteContext中的异常属性为null_C#_Exception_Asp.net Core 3.0 - Fatal编程技术网

C# WebAPI筛选器的ActionExecuteContext中的异常属性为null

C# WebAPI筛选器的ActionExecuteContext中的异常属性为null,c#,exception,asp.net-core-3.0,C#,Exception,Asp.net Core 3.0,我已经使用同一个异常过滤器好几个月了,到目前为止,它的性能非常好。这是: public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter { public int Order { get; set; } = int.MaxValue - 10; public void OnActionExecuting(ActionExecutingContext context) { }

我已经使用同一个异常过滤器好几个月了,到目前为止,它的性能非常好。这是:

public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
{
    public int Order { get; set; } = int.MaxValue - 10;

    public void OnActionExecuting(ActionExecutingContext context)
    {
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        if (context.Exception is HttpResponseException exception)
        {
            context.Result = new ObjectResult(new {Mensagem = context.Exception.Message})
            {
                StatusCode = exception.Status,
            };
            context.ExceptionHandled = true;
        }
        else if (context.Exception is Exception)
        {
            var message = context.Exception.InnerException != null ? context.Exception.InnerException.Message : context.Exception.Message;

            context.Result = new ObjectResult(new RetornoExceptionApi(message))
            {
                StatusCode = StatusCodes.Status500InternalServerError
            };

            context.ExceptionHandled = true;
        }
    }
}
简单明了。我一直在使用它来捕获自定义HTTP异常,其中HttpResponseException是基类。这就是它看起来的样子:

public class HttpResponseException : Exception
{
    public int Status { get; set; } = StatusCodes.Status500InternalServerError;

    public HttpResponseException(int statusCode)
    {
        Status = statusCode;
    }
}
没什么。这是404状态代码的自定义例外:

public class NotFoundException404<TKey> : HttpResponseException
{
    private string _message;

    public NotFoundException404(TKey id) : base(StatusCodes.Status404NotFound)
    {
        _message = $"Nenhum objeto encontrado! ID solicitado: { id }";
    }
    public NotFoundException404(long id) : base(StatusCodes.Status404NotFound)
    {
        _message = $"Nenhum objeto encontrado! ID solicitado: { id }";
    }
    public NotFoundException404(string message) : base(StatusCodes.Status404NotFound)
    {
        _message = message;
    }

    public override string Message => _message;
}
此异常是从与HTTP其他异常相同的基本服务引发的,例如:

    protected async Task DeleteAsync(TKey id)
    {
        var entidade = await GetEntidadeExclusaoAsync(id);
        try
        {
            await _repository.DeleteAsync(entidade);
        }
        catch (SqlException e) when (e.Number == 547)
        {
            throw new ForeignKeyViolationException();
        }
        catch (Exception ex)
        {
            if (ex.InnerException != null
                && ex is SqlException
                && ((SqlException)ex).Number == 547)
                throw new ForeignKeyViolationException();
        }
    }

那个不起作用的异常在我的过滤器中为空,我不知道为什么。有什么建议吗?

这里的主要问题似乎是我很愚蠢。我停下来以更彻底的方式检查代码,问题不在于过滤器,而是我如何尝试提出ForeignKeyViolationException。这:

应该是这样的:

    catch (Exception ex)
    {
        if (ex.InnerException != null
            && ex.InnerException is SqlException
            && ((SqlException)ex.InnerException).Number == 547)
            throw new ForeignKeyViolationException();
        else
            throw ex;
    }
德普

更新

johnny 5的答案更简洁,效果也更完美,这无疑是首选的解决方法:

catch (Exception ex) when ((ex.InnerException as SqlException)?.Number == 547)
{
    throw new ForeignKeyViolationException();
}

看起来你已经找到问题的答案了。不过,我会努力建立在你的答案之上。可以使用when子句使函数更具可读性

catch (Exception ex) when ((ex.InnerException as SqlException)?.Number == 547) {
    throw new ForeignKeyViolationException();
}

我认为您犯了一个错误,SqlExceptionex.InnerExceptionex应该这样读:SqlExceptionex.InnerException。请参阅我的答案以了解优化和改进readability@johnny5是的,我在传递代码时搞砸了,只是更新了我的答案。我会尝试一下你的外观,测试后再更新一次。我不知道这样的时候你还能用。事实上,直到上周我才知道你什么时候起床。顺便说一句,您遗漏了几个括号,编译器仅在ex.InnerException作为SqlException?时才允许。Number==547
    catch (Exception ex)
    {
        if (ex.InnerException != null
            && ex.InnerException is SqlException
            && ((SqlException)ex.InnerException).Number == 547)
            throw new ForeignKeyViolationException();
        else
            throw ex;
    }
catch (Exception ex) when ((ex.InnerException as SqlException)?.Number == 547)
{
    throw new ForeignKeyViolationException();
}
catch (Exception ex) when ((ex.InnerException as SqlException)?.Number == 547) {
    throw new ForeignKeyViolationException();
}