Asp.net Core MVC自定义异常处理:如何在前端显示提示弹窗?
C#后端自定义异常前端弹窗提示实现方案
一、服务端全局异常处理(ASP.NET Core)
1. 定义自定义异常类
创建业务专属异常类,区分系统异常与业务异常:
public class CustomBusinessException : Exception { // 自定义状态码,默认400(客户端错误) public int StatusCode { get; set; } = StatusCodes.Status400BadRequest; public CustomBusinessException(string message) : base(message) { } public CustomBusinessException(string message, int statusCode) : base(message) { StatusCode = statusCode; } }
2. 实现全局异常处理中间件
通过中间件捕获全链路异常,返回统一格式的JSON响应:
public class GlobalExceptionMiddleware { private readonly RequestDelegate _next; private readonly ILogger<GlobalExceptionMiddleware> _logger; public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (CustomBusinessException ex) { _logger.LogError(ex, "业务异常触发"); await HandleCustomException(context, ex); } catch (Exception ex) { _logger.LogError(ex, "未捕获系统异常"); await HandleSystemException(context, ex); } } private static async Task HandleCustomException(HttpContext context, CustomBusinessException ex) { context.Response.ContentType = "application/json"; context.Response.StatusCode = ex.StatusCode; var result = new { Success = false, Message = ex.Message, ErrorCode = ex.StatusCode }; await context.Response.WriteAsJsonAsync(result); } private static async Task HandleSystemException(HttpContext context, Exception ex) { context.Response.ContentType = "application/json"; context.Response.StatusCode = StatusCodes.Status500InternalServerError; var result = new { Success = false, Message = "服务器内部错误,请稍后重试", ErrorCode = 500 }; await context.Response.WriteAsJsonAsync(result); } } // 扩展方法简化中间件注册 public static class GlobalExceptionMiddlewareExtensions { public static IApplicationBuilder UseGlobalExceptionHandler(this IApplicationBuilder app) { return app.UseMiddleware<GlobalExceptionMiddleware>(); } }
3. 注册中间件
在Program.cs中按正确顺序注册(必须放在UseRouting之后,UseEndpoints之前):
var app = builder.Build(); // 全局异常处理中间件 app.UseGlobalExceptionHandler(); app.UseRouting(); // 其他中间件(授权、静态文件等) app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
4. 业务逻辑中抛异常
在控制器或业务层直接抛出自定义异常:
[ApiController] [Route("api/user")] public class UserController : ControllerBase { [HttpPost("register")] public async Task<IActionResult> Register(UserDto dto) { // 模拟用户名已存在校验 if (await CheckUserExists(dto.UserName)) { throw new CustomBusinessException("该用户名已被注册,请更换"); } // 注册逻辑... return Ok(new { Success = true, Message = "注册成功" }); } private Task<bool> CheckUserExists(string userName) { // 模拟数据库查询 return Task.FromResult(true); } }
二、前端异常捕获与弹窗提示
以Axios为例,通过全局响应拦截器捕获异常并弹窗:
// Axios全局响应拦截器 axios.interceptors.response.use( response => response, error => { if (error.response?.data) { const res = error.response.data; if (!res.Success) { // 原生弹窗或UI框架弹窗(如Element UI的$message) alert(res.Message); // Vue项目可替换为:this.$message.error(res.Message); // React项目可替换为:message.error(res.Message); } } else if (error.request) { alert("请求超时,请检查网络连接"); } else { alert(`请求配置错误:${error.message}`); } return Promise.reject(error); } );
三、ASP.NET Framework 兼容方案
若使用传统ASP.NET Framework,在Global.asax中通过Application_Error处理全局异常:
protected void Application_Error(object sender, EventArgs e) { var exception = Server.GetLastError(); Server.ClearError(); var responseData = new { Success = false, Message = exception is CustomBusinessException ex ? ex.Message : "服务器内部错误" }; Response.ContentType = "application/json"; Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(responseData)); Response.End(); }
关键注意事项
- 中间件顺序:全局异常中间件必须在路由中间件之后注册,否则无法捕获控制器内的异常
- 异常分级:业务异常返回用户友好提示,系统异常返回通用提示避免泄露敏感信息
- 统一格式:服务端所有接口返回
Success/Message/Data的统一结构,前端按该结构处理即可
内容的提问来源于stack exchange,提问作者Faithful Eli Coronel
相关产品推荐
相关产品推荐

