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

ASP.NET Core SignalR中如何序列化发送含抽象类子类的对象

解决SignalR序列化抽象类子类属性的问题

方案一:给System.Text.Json开启多态支持

SignalR默认使用System.Text.Json处理序列化,它不会自动识别抽象类的子类,导致子类独有的属性被截断。直接在配置中添加多态规则即可解决:

  1. 在Program.cs中配置SignalR的Json协议:
builder.Services.AddSignalR()
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                typeInfo =>
                {
                    if (typeInfo.Type == typeof(WidgetData))
                    {
                        typeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                        {
                            TypeDiscriminatorPropertyName = "$type", // 新增类型标识字段,客户端靠这个区分子类
                            IgnoreUnrecognizedTypeDiscriminators = true,
                            DerivedTypes =
                            {
                                new JsonDerivedType(typeof(ValueIndicatorData), nameof(ValueIndicatorData)),
                                // 把所有WidgetData的子类都添加到这里
                                // new JsonDerivedType(typeof(XXXData), nameof(XXXData))
                            }
                        };
                    }
                }
            }
        };
    });
  1. Angular客户端根据$type字段转换对应类型:
    先定义好TypeScript接口:
interface WidgetData {
  widgetUsageId: string;
  timestamp: string;
  $type?: string;
}

interface ValueIndicatorData extends WidgetData {
  valueIndicatorValues: ValueIndicatorValue[];
}

interface ValueIndicatorValue {
  // 对应C#类的属性
}

再处理收到的数据:

handleDashboardData(dataBatch: { dashboardId: string; widgetData: WidgetData[]; refreshDate: string }) {
  const typedWidgets = dataBatch.widgetData.map(item => {
    switch(item.$type) {
      case 'ValueIndicatorData':
        return item as ValueIndicatorData;
      // 其他子类的判断case按需添加
      default:
        return item;
    }
  });
}

方案二:改用Newtonsoft.Json处理序列化

如果觉得System.Text.Json的配置繁琐,可以切换到对多态支持更成熟的Newtonsoft.Json:

  1. 安装NuGet包:Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson
  2. 在Program.cs中配置SignalR使用NewtonsoftJson:
builder.Services.AddSignalR()
    .AddNewtonsoftJsonProtocol(options =>
    {
        options.PayloadSerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
        // 也可选择TypeNameHandling.Objects,根据实际需求调整
    });
  1. 客户端同样通过返回的$type字段区分类型,处理逻辑和方案一一致。

方案三:手动添加类型标识(无需修改全局配置)

不想改动全局序列化配置的话,可以直接在父类中新增类型标识属性,让每个子类自行返回类型名称:

  1. 修改C#类:
public abstract class WidgetData
{
    public Guid WidgetUsageId { get; set;}
    public DateTime Timestamp { get; set;}
    public abstract string WidgetType { get; } // 子类必须实现该属性
}

public class ValueIndicatorData : WidgetData
{
    public override string WidgetType => nameof(ValueIndicatorData);
    public IList<ValueIndicatorValue> ValueIndicatorValues { get; } = new List<ValueIndicatorValue>();
}
  1. 客户端收到数据后,根据widgetType字段判断类型,转换为对应的子类对象即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:10:35