可能有一些其他的方式來做到這一點(我不宣稱自己是一個ASP.Net核心專家),但我已經解決了這個問題,下面的方法。首先,定義一個自定義的異常類。目的是,你可以實際上扔這不考慮任何控制器方法返回類型。而且,拋出異常使得控制流程更加結構化。
public class CustomApiException : Exception
{
/// <summary>
/// Optional application-specific error code returned to the client.
/// </summary>
public int? ApplicationErrorCode { get; private set; } = null;
/// <summary>
/// HTTP status code returned to the client.
/// </summary>
public HttpStatusCode HttpStatusCode { get; private set; } = HttpStatusCode.BadRequest;
public CustomApiException() : base() { }
public CustomApiException(string message) : base(message) { }
public CustomApiException(string message, HttpStatusCode httpStatusCode) : base(message)
{
HttpStatusCode = httpStatusCode;
}
public CustomApiException(string message, HttpStatusCode httpStatusCode, int? applicationErrorCode) : base(message)
{
HttpStatusCode = httpStatusCode;
ApplicationErrorCode = applicationErrorCode;
}
public CustomApiException(string message, int? applicationErrorCode) : base(message)
{
ApplicationErrorCode = applicationErrorCode;
}
}
然後定義一個自定義的ExceptionFilterAttribute。請注意,此複製/粘貼片段比您要求的要多一點。例如。取決於開發與生產,它將包括異常的整個堆棧跟蹤(實際上是任何異常,而不僅僅是CustomApiException)。
// todo: turn into async filter.
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
private readonly ILogger<ApiExceptionFilterAttribute> _logger;
private readonly IHostingEnvironment _env;
public ApiExceptionFilterAttribute(ILogger<ApiExceptionFilterAttribute> logger, IHostingEnvironment env)
{
_logger = logger;
_env = env;
}
public override void OnException(ExceptionContext context)
{
_logger.LogError(new EventId(0), context.Exception, context.Exception.Message);
dynamic errObject = new JObject();
HttpStatusCode statusCode = HttpStatusCode.InternalServerError; // use 500 unless the API says it's a client error
if (context.Exception.GetType() == typeof(CustomApiException))
{
CustomApiException customEx = (CustomApiException)context.Exception;
if (customEx.ApplicationErrorCode != null) errObject.errorCode = customEx.ApplicationErrorCode;
errObject.errorMessage = customEx.Message;
statusCode = customEx.HttpStatusCode;
}
if (_env.IsDevelopment())
{
errObject.errorMessage = context.Exception.Message;
errObject.type = context.Exception.GetType().ToString();
errObject.stackTrace = context.Exception.StackTrace;
}
JsonResult result = new JsonResult(errObject);
result.StatusCode = (int?)statusCode;
context.Result = result;
}
}
最後,將自定義ExceptionFilterAttribute添加到全局ConfigureServices方法中。
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//...
// Add framework services.
services.AddMvc(options =>
{
options.Filters.Add(typeof(ApiExceptionFilterAttribute));
});
}
// ...
}
這是一個有點工作,但只有一次性的工作,並且一旦你添加它,功能就非常強大。如果我沒有記錯,我的解決方案是基於這個MS頁面Exception Handling。如果您還有其他問題,這可能會有所幫助。
這是堅實的。它測試每個級別。我會遵循這一點。謝謝 – user2320476
@ user2320476很高興能幫到你。有機會時請閱讀[this](https://stackoverflow.com/help/someone-answers)。 – CodingYoshi