【问题标题】:What IActionResult to return from a WebSocket request in ASP.NET Core?从 ASP.NET Core 中的 WebSocket 请求返回什么 IActionResult?
【发布时间】:2018-11-29 00:21:10
【问题描述】:

我有一个 ASP.NET Core 2.1 webapi 正在运行,它正在侦听 Web 套接字请求。如果请求不是针对 WebSocket 升级,我想 return this.BadRequest()

[Route("api/[controller]")]
[ApiController]
public class SocketController : ControllerBase
{
    [HttpGet]
    public async Task<IActionResult> Post()
    {
        if (!this.HttpContext.WebSockets.IsWebSocketRequest)
            return this.BadRequest();

        using (var webSocket = await this.HttpContext.WebSockets.AcceptWebSocketAsync())
        {
            using (var jsonRpc = new JsonRpc(new WebSocketMessageHandler(webSocket)))
            {
                jsonRpc.AddLocalRpcTarget(new SocketServer());
                jsonRpc.StartListening();
                await jsonRpc.Completion;
            }
        }

        return this.Ok();
    }
}

但是无论是走成功路径还是失败路径,服务端都会抛出异常:

失败:Microsoft.AspNetCore.Server.Kestrel[13] 连接 ID“0HLEM87126JEO”,请求 ID“0HLEM87126JEO:00000001”:应用程序引发了未处理的异常。 System.InvalidOperationException:无法设置 StatusCode,因为响应已经开始。 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(字符串值) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 值) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 值) 在 Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode(Int32 值) 在 Microsoft.AspNetCore.Mvc.StatusCodeResult.ExecuteResult(ActionContext 上下文) 在 Microsoft.AspNetCore.Mvc.ActionResult.ExecuteResultAsync(ActionContext 上下文) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult 结果) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsyncTFilter,TFilterAsync 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext 上下文) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext 上下文) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() 在 Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 应用程序)

如果我将方法更改为只返回 Task 就可以了,这样我就不必提供 IActionResult,但是我没有办法对错误请求返回 400 响应。解决此问题的最佳方法是什么?

我的中间件超级简单:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            // app.UseHsts();
        }

        // app.UseHttpsRedirection();
        app.UseWebSockets();
        app.UseMvc();
    }

【问题讨论】:

  • 问题是 websocket 处理程序可能已经发送了一些东西来进行通信。我想有一种方法可以使用当前的 HttpContext 来提供响应,而不是通过从函数返回来提供响应。不过我对asp.net一无所知。
  • 很可能由于套接字请求,管道中较高的中间件已经开始响应。应该在那里开始调查
  • 谢谢,@nkosi。我的中间件超级简单。我已将其添加到我的问题中。

标签: c# asp.net-core websocket asp.net-core-mvc


【解决方案1】:

秘密是EmptyResult,没有this.Empty()方法。

public async Task<IActionResult> Post()
{
    if (!this.HttpContext.WebSockets.IsWebSocketRequest)
    {
        return this.BadRequest();
    }

    using (var webSocket = await this.HttpContext.WebSockets.AcceptWebSocketAsync())
    {
        using (var jsonRpc = new JsonRpc(new WebSocketMessageHandler(webSocket)))
        {
            jsonRpc.AddLocalRpcTarget(new SocketServer());
            jsonRpc.StartListening();
            await jsonRpc.Completion;
        }
    }

    return new EmptyResult();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2017-11-06
    • 2017-05-18
    相关资源
    最近更新 更多