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

SignalR源代码生成器始终抛出异常问题求助

问题:SignalR源代码生成器未生成预期的Hub代理逻辑,抛出ArgumentException

问题场景

自定义了以下特性与扩展方法:

[AttributeUsage(AttributeTargets.Method)]
internal class HubClientProxyAttribute : Attribute { }

[AttributeUsage(AttributeTargets.Method)]
internal class HubServerProxyAttribute : Attribute { }

public static partial class HubConnectionExtensions
{
    [HubClientProxy]
    public static partial IDisposable Subscribe<T>(this HubConnection connection, T provider);

    [HubServerProxy]
    public static partial T HubInvoker<T>(this HubConnection connection);
}

但源代码生成器生成的文件中,方法仅抛出ArgumentException,未生成预期的代理逻辑:

// HubClientProxy.g.cs
public static partial System.IDisposable Subscribe<T>(this HubConnection connection, T provider)
{
    if (provider is null)
    {
        throw new System.ArgumentNullException("provider");
    }

    throw new System.ArgumentException(nameof(T)); // 未生成代理逻辑
}

// HubServerProxy.g.cs
public static partial T HubInvoker<T>(this HubConnection connection)
{
    throw new System.ArgumentException(nameof(T)); // 未生成代理逻辑
}

在AppService中调用Subscribe时触发异常(AppService与Hub实现同一接口):

public AppService(IHttpClientFactory clientFactory, ILogger<AppService> logger)
{
    _logger = logger;
    _client = clientFactory.CreateClient("clientname");
    _hub = new HubConnectionBuilder().WithUrl($"{_client.BaseAddress!.GetLeftPart(UriPartial.Authority)}/hubpath").Build();
    _subscriber = _hub.Subscribe(this); // 此处触发异常

    _dataTaskSource = InitializeDataTaskSource();
}

解决步骤

1. 确保泛型参数T为接口类型

源代码生成器仅针对接口类型生成代理逻辑。当前调用_hub.Subscribe(this)时,泛型参数T是AppService类(而非接口),生成器无法识别并生成代理。需要显式指定接口类型:

// 假设AppService实现了IMyHub接口
_subscriber = _hub.Subscribe<IMyHub>(this);

2. 调整特性的可见性

你的HubClientProxyAttribute和HubServerProxyAttribute标记为internal,如果源代码生成器所在的程序集无法访问内部类型,会导致生成逻辑失效。将特性改为public:

[AttributeUsage(AttributeTargets.Method)]
public class HubClientProxyAttribute : Attribute { }

[AttributeUsage(AttributeTargets.Method)]
public class HubServerProxyAttribute : Attribute { }

如果必须保持internal,可在项目中添加InternalsVisibleTo特性,允许生成器程序集访问内部类型:

[assembly: InternalsVisibleTo("Microsoft.AspNetCore.SignalR.Client.SourceGenerator")]

3. 验证源代码生成器依赖与配置

  • 确认项目已引用正确的源代码生成器包,版本需与SignalR客户端版本匹配:
    <PackageReference Include="Microsoft.AspNetCore.SignalR.Client.SourceGenerator" Version="7.0.0" />
    
  • 检查项目文件是否启用源代码生成(SDK风格项目默认启用,若有禁用需开启):
    <PropertyGroup>
      <EnableSourceGeneration>true</EnableSourceGeneration>
    </PropertyGroup>
    

4. 检查接口方法的合规性

确保Hub接口的方法符合SignalR要求:

  • 返回类型必须是Task或Task<T>
  • 参数类型需支持JSON序列化(避免使用ref/out参数、非序列化类型)
  • 方法名称需与Hub端的方法名称完全匹配

5. 清理缓存并重新生成

删除项目的bin和obj文件夹,清理生成缓存,然后重新生成整个解决方案,确保源代码生成器重新执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:35:33