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

.Net 服务端如何获取SignalR客户端上报异常的完整信息

问题原因

SignalR默认的JSON序列化器不会完整序列化Exception类型的所有成员:Exception的核心属性如StackTrace、HResult等多为只读属性,默认序列化规则不会处理这类属性,且Exception存在循环引用结构(如InnerException嵌套),最终反序列化到服务端时只会生成一个默认的空Exception实例,因此只会返回通用提示。

推荐解决方案(手动构造可序列化DTO)

不要直接传输Exception对象,自定义日志传输类,手动提取需要的异常字段,该方案可控性高、无安全风险、兼容性好:

  1. 客户端定义传输DTO
public class ExceptionLogDto
{
    // 可根据需要扩展字段,比如错误码、发生时间、客户端标识等
    public string ExceptionType { get; set; }
    public string Message { get; set; }
    public string StackTrace { get; set; }
    public string InnerExceptionInfo { get; set; }
}
  1. 修改客户端上报逻辑
private async Task LogCallBack(Exception ex)
{
    try
    {
        var logDto = new ExceptionLogDto
        {
            ExceptionType = ex.GetType().FullName,
            Message = ex.Message,
            StackTrace = ex.StackTrace,
            InnerExceptionInfo = ex.InnerException?.ToString()
        };
        await Send("ClientLogs", logDto);
    }
    catch (Exception sendEx)
    {
        Serilog.Log.Error($"日志上报失败 - {sendEx}");
    }
}
  1. 修改服务端接收逻辑
public void ClientLogs(ExceptionLogDto logDto)
{
    Serilog.Log.Error("客户端上报异常:类型={Type}, 消息={Message}, 堆栈={StackTrace}, 内部异常={Inner}", 
        logDto.ExceptionType, logDto.Message, logDto.StackTrace, logDto.InnerExceptionInfo);            
}
其他可选方案(不推荐)

如果一定要直接传输Exception对象,需要统一配置服务端和客户端的SignalR序列化规则,以Newtonsoft.Json为例:

  1. 服务端配置序列化规则
builder.Services.AddSignalR()
    .AddNewtonsoftJsonProtocol(opt =>
    {
        opt.PayloadSerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
        opt.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });
  1. 客户端也要对应使用Newtonsoft.Json序列化器,且保持序列化参数和服务端一致。
    该方案存在序列化失败、敏感信息泄露、传输体积大等问题,非必要不使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:45:01