从ASP.NET Core中的WebSocket请求返回什么IActionResult?

时间:2018-06-20 00:15:22

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

我正在运行一个正在侦听Web套接字请求的ASP.NET Core 2.1 webapi。如果请求不是针对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](状态和下一个,范围和范围,对象和状态,布尔值和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(状态和下一个,范围和范围,对象和状态,布尔值和已完成)      在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();
    }

1 个答案:

答案 0 :(得分:3)

秘密是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();
}
相关问题