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

C# WebForms中如何将完整异常对象传递至错误处理页面?

如何将完整Exception对象传递到自定义错误处理页面?

我正在创建自定义错误处理页面(如Oops.aspx),希望能把完整的Exception对象传递过去,这样就能在页面里分析错误(比如遍历StackTrace的帧)、记录错误,同时给用户展示友好提示。

之前尝试过几种方法都有问题:

  • 直接用Response.Redirect传递对象,出现换行错误
  • 用HttpUtility.UrlEncode把对象转字符串,行不通
  • 直接转字符串会丢失大量数据
  • 目前只能传递零散的字符串字段,但能获取的信息远不如完整对象多

示例代码(期望的错误分析逻辑)

var stackTrace = new StackTrace(ex, true);
var allframes = stackTrace.GetFrames().ToList();
foreach(var frame in allframes)
{
    var filename = frame.GetFileName();
    var linenumber = frame.GetFileLineNumber();
    var method = frame.GetMethod();
    var MethodName = method.Name;
    var Classname = frame.GetMethod().DeclaringType.ToString();
}

尝试过的代码(无效)

HttpContext.Current.Response.Redirect(String.Format("~/Oops.aspx/Error=?{0}",ex));

当前使用的代码(只能传递零散字段)

HttpContext.Current.Response.Redirect(string.Format("~/Oops.aspx?Error={0}&StackTrace={1}&InnerException={2}&Data={3}&Source={4}&TargetSite={5}&Hresult={6}", ex.Message, ex.StackTrace, ex.InnerException, ex.Data, ex.Source, ex.TargetSite, ex.HResult));

可行的解决方案

1. 使用Session存储Exception对象

把Exception存入Session后跳转,错误页从Session取出处理,完成后清理Session避免内存浪费。

错误发生时的代码:

HttpContext.Current.Session["ErrorException"] = ex;
HttpContext.Current.Response.Redirect("~/Oops.aspx");

Oops.aspx后台处理代码:

protected void Page_Load(object sender, EventArgs e)
{
    if (Session["ErrorException"] is Exception ex)
    {
        // 执行你的错误分析、记录逻辑
        var stackTrace = new StackTrace(ex, true);
        var allframes = stackTrace.GetFrames().ToList();
        foreach(var frame in allframes)
        {
            var filename = frame.GetFileName();
            var linenumber = frame.GetFileLineNumber();
            var method = frame.GetMethod();
            var MethodName = method.Name;
            var Classname = frame.GetMethod().DeclaringType.ToString();
            // 这里添加记录或展示逻辑
        }
        
        // 处理完毕后移除Session中的对象
        Session.Remove("ErrorException");
    }
}

注意:需确保网站已启用会话状态(如InProc模式),否则Session无法正常使用。

2. 使用Server.Transfer传递对象

Server.Transfer是服务器端页面跳转,不会发起新的HTTP请求,可通过Context.Items直接传递对象。

错误发生时的代码:

HttpContext.Current.Items["ErrorException"] = ex;
HttpContext.Current.Server.Transfer("~/Oops.aspx");

Oops.aspx后台处理代码:

protected void Page_Load(object sender, EventArgs e)
{
    if (Context.Items["ErrorException"] is Exception ex)
    {
        // 处理完整的Exception对象
        var stackTrace = new StackTrace(ex, true);
        // ... 你的分析和记录逻辑
    }
}

注意:使用Server.Transfer后,浏览器地址栏不会更新为错误页的URL,用户看到的仍是原页面地址。

3. 序列化Exception到内存缓存

如果Session不可用,可将Exception序列化后存入内存缓存,通过URL传递缓存Key,错误页再取出反序列化处理。

错误发生时的代码:

using System.Text.Json;
using System.Web.Caching;

// 生成唯一缓存Key
var errorKey = Guid.NewGuid().ToString();
// 序列化Exception(处理循环引用问题)
var json = JsonSerializer.Serialize(ex, new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.IgnoreCycles });
// 存入缓存,设置5分钟过期时间
HttpContext.Current.Cache.Insert(errorKey, json, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration);
// 跳转到错误页并传递Key
HttpContext.Current.Response.Redirect($"~/Oops.aspx?errorKey={errorKey}");

Oops.aspx后台处理代码:

using System.Text.Json;

protected void Page_Load(object sender, EventArgs e)
{
    var errorKey = Request.QueryString["errorKey"];
    if (!string.IsNullOrEmpty(errorKey))
    {
        var cachedJson = HttpContext.Current.Cache[errorKey] as string;
        if (cachedJson != null)
        {
            // 反序列化回Exception对象
            var ex = JsonSerializer.Deserialize<Exception>(cachedJson, new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.IgnoreCycles });
            if (ex != null)
            {
                // 处理错误逻辑
                var stackTrace = new StackTrace(ex, true);
                // ...
            }
            // 清理缓存
            HttpContext.Current.Cache.Remove(errorKey);
        }
    }
}

注意:Exception对象包含循环引用,序列化时需配置忽略循环引用;避免使用存在安全风险的BinaryFormatter,优先用JsonSerializer。


内容的提问来源于stack exchange,提问作者Michael Wood

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:07:16