You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core异常中间件中处理Ajax请求的日志与重定向?

解决ASP.NET Core MVC全局异常中间件在Ajax请求下的问题

你的问题核心在于:Ajax请求是异步HTTP请求,浏览器不会自动处理Redirect响应——因为Ajax请求的响应会被JavaScript代码接收,而非直接由浏览器解析执行跳转指令。要实现记录错误+跳转自定义错误页面的需求,需要区分请求类型分别处理:

解决方案:区分Ajax与非Ajax请求处理响应

修改你的异常中间件,先判断当前请求是否为Ajax请求,再分别返回对应响应:

  1. 判断Ajax请求:通过检查请求头X-Requested-With是否等于XMLHttpRequest(这是大多数前端框架发起Ajax请求时会自动携带的标准头)。
  2. Ajax请求处理:返回JSON格式的错误信息(包含错误页URL),然后由前端JavaScript接收后执行页面跳转。
  3. 非Ajax请求处理:保持原有的Redirect逻辑即可。

修改后的中间件代码

public class AppExceptionMiddleware: IMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var _service = context.RequestServices.GetRequiredService<IUserAccountService>();

        try
        {
            await next(context);
        }
        catch (Exception error)
        {
            // 统一记录错误到数据库
            var routeData = context.GetRouteData();
            var controllerName = routeData?.Values["controller"]?.ToString() ?? "Unknown";
            var actionName = routeData?.Values["action"]?.ToString() ?? "Unknown";
            var areaName = routeData?.Values["area"]?.ToString() ?? " ";

            _service.LogAppException(new Application.ViewModels.ErrorLogModel
            {
                errorMessage = error.Message,
                errorSource = error.Source,
                errorXML = error.ToString(),
                errorType = error.GetType().Name,
                controllerName = controllerName,
                actionName = actionName,
                areaName = areaName
            });

            // 判断是否为Ajax请求
            bool isAjaxRequest = context.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
            
            if (isAjaxRequest)
            {
                // 针对Ajax请求返回JSON响应,包含错误页URL
                context.Response.ContentType = "application/json";
                context.Response.StatusCode = StatusCodes.Status200OK; // 也可根据需求使用500状态码
                await context.Response.WriteAsJsonAsync(new
                {
                    Success = false,
                    ErrorMessage = "服务器发生异常,请稍后重试",
                    RedirectUrl = "/error/oops"
                });
            }
            else
            {
                // 非Ajax请求直接跳转错误页
                context.Response.Redirect("/error/oops");
            }
        }
    }
}

前端配合处理(可选)

如果返回JSON格式响应,需要在前端Ajax请求的错误回调中处理跳转:

// 示例:jQuery Ajax请求
$.ajax({
    url: "/your-api-endpoint",
    type: "POST",
    data: yourData,
    success: function(result) {
        // 正常处理逻辑
    },
    error: function(xhr) {
        var response = JSON.parse(xhr.responseText);
        if (response.RedirectUrl) {
            window.location.href = response.RedirectUrl;
        }
    }
});

额外说明

  • 若希望强制浏览器跳转(无需前端JS处理),也可给Ajax请求返回302状态码并设置Location头,但部分前端框架可能会自动跟随重定向并返回重定向后的页面内容,而非触发浏览器跳转,因此返回JSON让前端主动跳转是更可靠的方案。
  • 确保/error/oops路由已正确映射到对应的错误页控制器和视图。

内容的提问来源于stack exchange,提问作者Mark Adesina Omoniyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:17:21