System.InvalidOperationException: OnStarting не может быть установлен, поскольку ответ уже запущен

1
8

Я создаю плагины (проекты) для NopCommerce (проект .NET MVC). У меня есть два независимых плагина (проекта). Один для предоставления API, а другой для поддержки в чате в реальном времени. Для чата в реальном времени я использую SignalR. И стек вызовов ошибок -

Не могу решить эту проблему. Ниже приведен файл запуска моего плагина (проекта) API.

А это файл запуска моего плагина чата (проекта) в реальном времени:

А это MessageHub из проекта плагина чата в реальном времени.

Microsoft.AspNetCore.SignalR.HubConnectionHandler: Error: Error when dispatching 'OnConnectedAsync' on hub.

System.InvalidOperationException: OnStarting cannot be set because the response has already started.
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(String value)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.OnStarting(Func`2 callback, Object state)
   at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.InitializeHandlerAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Nop.Services.Authentication.CookieAuthenticationService.GetAuthenticatedCustomerAsync()
   at Nop.Plugin.API.Services.BearerTokenOrCookieAuthenticationService.GetAuthenticatedCustomerAsync()
   at Nop.Web.Framework.WebWorkContext.SetCurrentCustomerAsync(Customer customer) 
   at Nop.Web.Framework.WebWorkContext.GetCurrentCustomerAsync() 
   at Nop.Plugin.Widgets.RealTimeChat.Hubs.MessageHub.IsAuthenticated() in Documents\nopCommerce\src\Plugins\Nop.Plugin.Widgets.RealTimeChat\Hubs\MessageHub.cs:line 63
   at Nop.Plugin.Widgets.RealTimeChat.Hubs.MessageHub.OnConnectedAsync() in nopCommerce\src\Plugins\Nop.Plugin.Widgets.RealTimeChat\Hubs\MessageHub.cs:line 23
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnConnectedAsync(HubConnectionContext connection)
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnConnectedAsync(HubConnectionContext connection)
   at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.RunHubAsync(HubConnectionContext connection)
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executed endpoint '/messageHub'
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{         
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, jwtBearerOptions =>
    {
        jwtBearerOptions.TokenValidationParameters = //token validation parameter
        jwtBearerOptions.Events = new JwtBearerEvents
        {
            OnChallenge = context =>
            {
                context.HandleResponse();
                context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                context.Response.ContentType = "application/json";
                var result = JsonConvert.SerializeObject(new { error = "Unauthorized access" });
                return context.Response.WriteAsync(result);
            }
        };
    });
    
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    AddAuthorizationPipeline(services);
 
    services.Configure<KestrelServerOptions>(options =>
    {
        options.AllowSynchronousIO = true;
    });
    services.Configure<IISServerOptions>(options =>
    {
        options.AllowSynchronousIO = true;
    });
    services.Configure<MvcNewtonsoftJsonOptions>(options =>
    {
        options.SerializerSettings.Converters.Add(new StringEnumConverter());
    });

    services.AddControllers();
    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new OpenApiInfo
        {
            Version = "v1",
            Title = "nop commerce mobile api"
        });
    });

    services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigSwaggerOptions>();

    services.AddCors(opt =>
    {
        opt.AddPolicy(name: "CorsPolicy", builder =>
        {
            builder
                .AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod();
        });
    });
}
 
public void Configure(IApplicationBuilder app)
{
    var environment = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();

    var rewriteOptions = new RewriteOptions().AddRewrite("api/token", "/token", true);
    app.UseRewriter(rewriteOptions);

    app.UseCors("CorsPolicy"); 

    app.MapWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), a =>
    {
        a.Use(async (context, next) =>
        {
            context.Request.EnableBuffering();
            await next();
        });

        // Authentication and authorization
        a.UseAuthentication();
        a.UseAuthorization();

        // Routing and endpoints
        a.UseRouting();
        a.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    });

    // Swagger configuration
    app.UseSwagger(options => options.RouteTemplate = "api/swagger/{documentName}/swagger.json");
    app.UseSwaggerUI(options =>
    {
        options.RoutePrefix = "api/swagger";
        options.SwaggerEndpoint("/api/swagger/v1/swagger.json", "Nop API v1");
    });
}  
public void Configure(IApplicationBuilder application)
{
    application.UseRouting();
    application.UseAuthorization();
    application.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<MessageHub>(RealTimeChatConstants.HubConnectionRoute);
    });
}

public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
    services.AddSignalR(r =>
    {
        r.EnableDetailedErrors = true;
    });

    //register services
}
public class MessageHub : Hub
{
    //fields and ctor
    
    public override async Task OnConnectedAsync()
    {
        if (!await IsAuthenticated())
        {
            return;
        }

        var currentCustomer = await _workContext.GetCurrentCustomerAsync();

        var existingUser = _connectedUsers.FirstOrDefault(x => x.UserId == currentCustomer.Id);
        if (existingUser == null)
        {
            _connectedUsers.Add(new UserConnection { ConnectionId = Context.ConnectionId, UserId = currentCustomer.Id });
        }
        else
        {
            existingUser.ConnectionId = Context.ConnectionId;
        }

        await base.OnConnectedAsync();
    }
}
Кир
Вопрос задан4 апреля 2024 г.

1 Ответ

2
Касьян
Ответ получен15 сентября 2024 г.

Ваш ответ

Загрузить файл.