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

JsonApiDotNetCore v5.0.3结合SignalR推送JSON:API格式数据方案咨询

针对JsonApiDotNetCore v5.0.3 + SignalR 推送JSON:API格式数据的解决方案

核心思路

直接复用JsonApiDotNetCore内置的JSON:API序列化服务,而非依赖SignalR默认序列化器或单独添加转换器(后者缺少资源元数据上下文支持,无法完成完整的JSON:API格式转换)。

具体实现步骤

1. 向SignalR Hub注入必要服务

在Hub的构造函数中注入IJsonApiSerializer和IResourceContextProvider:前者负责执行JSON:API格式的序列化逻辑,后者提供资源的元数据上下文(如字段定义、关系映射、资源类型信息等)。

using JsonApiDotNetCore.Serialization;
using JsonApiDotNetCore.Services;

public class NotificationHub : Hub
{
    private readonly IJsonApiSerializer _jsonApiSerializer;
    private readonly IResourceContextProvider _resourceContextProvider;

    public NotificationHub(IJsonApiSerializer jsonApiSerializer, IResourceContextProvider resourceContextProvider)
    {
        _jsonApiSerializer = jsonApiSerializer;
        _resourceContextProvider = resourceContextProvider;
    }

    // 推送方法写在此处
}

2. 手动序列化资源并推送

在推送数据时,先通过IResourceContextProvider获取对应资源的元数据上下文,再调用IJsonApiSerializer的序列化方法将对象转为符合JSON:API规范的字符串,最后通过SignalR发送该字符串。

推送单个资源示例

public async Task SendUpdatedProduct(Product updatedProduct)
{
    // 获取Product资源的元数据上下文
    var resourceContext = _resourceContextProvider.GetResourceContext(typeof(Product));
    
    // 序列化为JSON:API格式字符串
    string jsonApiPayload = await _jsonApiSerializer.SerializeAsync(updatedProduct, resourceContext, CancellationToken.None);
    
    // 推送给所有客户端
    await Clients.All.SendAsync("ReceiveProductUpdate", jsonApiPayload);
}

推送资源集合示例

public async Task SendNewProducts(IEnumerable<Product> newProducts)
{
    var resourceContext = _resourceContextProvider.GetResourceContext(typeof(Product));
    string jsonApiPayload = await _jsonApiSerializer.SerializeAsync(newProducts, resourceContext, CancellationToken.None);
    
    await Clients.All.SendAsync("ReceiveNewProducts", jsonApiPayload);
}

3. 处理关联资源(可选)

如果需要推送包含关联资源的数据,可通过IncludePaths参数指定要包含的关系,需额外注入IIncludeService来构建合法的包含路径:

using JsonApiDotNetCore.Inclusion;

// 在Hub构造函数中添加注入
private readonly IIncludeService _includeService;

public NotificationHub(IJsonApiSerializer jsonApiSerializer, IResourceContextProvider resourceContextProvider, IIncludeService includeService)
{
    _jsonApiSerializer = jsonApiSerializer;
    _resourceContextProvider = resourceContextProvider;
    _includeService = includeService;
}

public async Task SendProductWithCategory(Product product)
{
    var resourceContext = _resourceContextProvider.GetResourceContext(typeof(Product));
    // 构建包含"category"关联的路径
    var includePaths = _includeService.GetIncludePaths(new[] { "category" }, resourceContext);
    
    string jsonApiPayload = await _jsonApiSerializer.SerializeAsync(product, resourceContext, includePaths, CancellationToken.None);
    await Clients.All.SendAsync("ReceiveProductWithCategory", jsonApiPayload);
}

为什么之前的尝试无效?

  • 直接使用IJsonApiOptions.SerializerOptions:仅复制了序列化配置,但缺少JsonApiDotNetCore序列化必需的资源元数据上下文,无法解析资源的字段规则、关系映射等核心信息。
  • 仅添加ResourceObjectConverter:该转换器依赖ResourceContext才能正常工作,而SignalR默认序列化器无法自动注入该上下文,导致序列化逻辑不完整,无法生成符合规范的JSON:API数据。

内容的提问来源于stack exchange,提问作者Michiel van Vaardegem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:33:31