首页 > 解决方案 > Signalr 从服务器向客户端发送消息 c# 执行请求时发生未处理的异常

问题描述

我的错误:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Multiple constructors accepting all given argument types have been found in type 'AgencyApi.Controllers.LicenseInfoController'. There should only be one applicable constructor.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.TryFindMatchingConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& parameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& parameterMap)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactory(Type instanceType, Type[] argumentTypes)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.CreateActivator(ControllerActionDescriptor descriptor)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.CreateControllerFactory(ControllerActionDescriptor descriptor)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerCache.GetCachedResult(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerProvider.OnProvidersExecuting(ActionInvokerProviderContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker(ActionContext actionContext)
   at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointFactory.<>c__DisplayClass7_0.<CreateRequestDelegate>b__0(HttpContext context)"

我的 SignalRhub.cs

using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;

namespace AgencyApi
{
    public class SignalRHub:Hub
    {
        public async Task SendMessage(string user, string message)
            {
                await Clients.All.SendAsync("ReceiveMessage", user, message);
            }
        
    }
    
}

我的 LicenseInfoController.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using AgencyApi.Data.Entities;
using Microsoft.AspNetCore.Mvc;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Microsoft.AspNetCore.SignalR;
using AgencyApi;

namespace AgencyApi.Controllers
{
    [Route("api/[controller]")]
    public class LicenseInfoController : BaseController
    {
        private readonly ILicenseInfoService _licenseService;

        [HttpPost("ConfirmLink")]
        public async Task<JObject> ConfirmLink(LicenseInfo value)
        {
            JObject res = new JObject();
            try
            {
                var menuService = (IMenuService)this.HttpContext.RequestServices.GetService(typeof(IMenuService));
                var model = await _licenseService.GetById(value.id);
                model.Status = value.Status;
                model.Reason = value.Reason;
                var result = await _licenseService.Update(model);
                res.Add("ok", true);
                res.Add("data", JObject.FromObject(result));
            }
            catch (Exception ex)
            {
                res.Add("error", ex.Message);
            }   
            SendToAll();
            return res;
        }
        private readonly IHubContext<SignalRHub> _hubContext;

        public LicenseInfoController(IHubContext<SignalRHub> hubContext)
        {
            _hubContext = hubContext;
        }

        public void SendToAll()
        {
            _hubContext.Clients.All.SendAsync("Send", "message");
        }
    }
}

标签: c#asp.net-coresignalr

解决方案


我认为你正在复制一些不好的例子。我会建议一种不同的方法

让您将 SignalRinterface 作为服务,而不是衍生产品:

public class SignalRHub
{
    public Task SendMessage(string user, string message) =>
        _hubContext.Clients.All.SendAsync("ReceiveMessage", user, message);

    public Task SendToAll(string message) =>
        _hubContext.Clients.All.SendAsync("Send", message);

    private readonly IHubContext<Hub> _hubContext;

    public SignalRHub(IHubContext<Hub> hubContext) =>
        _hubContext = hubContext;
}

在启动中注册

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddSignalR();
    services.AddSingleton<SignalRHub>();
}

然后添加到控制器:

public class LicenseInfoController : Controller
{
    [HttpPost]
    public async Task<JObject> ConfirmLink(string value)
    {
        JObject res = new JObject();
        await _signalRHub.SendToAll("message");
        return res;
    }

    private readonly SignalRHub _signalRHub;

    public LicenseInfoController(SignalRHub signalRHub)
    {
        _signalRHub = signalRHub;
    }
}

推荐阅读