我正在运行一个正在侦听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();
}
答案 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();
}