You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asp.Net Core 7中Kestrel抛出BadHttpRequestException异常求助

Asp.Net Core 7快速点击按钮发起Ajax请求时后端异常问题

场景说明

前端用户每秒点击按钮发起Ajax请求,后端控制器处理请求时抛出Unexpected end of request content异常。

后端控制器代码

[ApiController]
[Route("api")]
public class FrontWcController : ControllerBase
{
    [HttpPost("change")]
    public IActionResult GetFromFrontSendToErp(ParametrsForButton requestData)
    {
        string wcGuid = requestData.WcGuid;
        string operation = requestData.Operation;
        string skusSerial = requestData.SkusSerial;
        string boxSerial = requestData.BoxSerial;
        int actionNumber = requestData.ActionNumber;
        int operationNumber = requestData.OperationNumber;
        int checkBox = requestData.CheckBox;

        string actionHumanString = "Undefined";

        switch (actionNumber)
        {
            case 1:
                actionHumanString = "Started";
                break;
            case 2:
                actionHumanString = "Pause";
                break;
            case 3:
                actionHumanString = "Finished";
                break;
            case 4:
                actionHumanString = "Exeption";
                break;
            case 5:
                actionHumanString = "Started";
                break;
            default:
                Console.WriteLine("Cant change status. Set to default");
                break;
        }

        DateTime dateTimeOfOperation = DateTime.UtcNow;
        
        MainIncomingChangesSaverList.IncomingChangesSaversList.Enqueue(new IncomingChangesSaver()
        {
            WcGuid = wcGuid,
            Operation = operation,
            SkusSerial = skusSerial,
            BoxSerial = boxSerial,
            ActionNumber = actionNumber,
            OperationNumber = operationNumber,
            CheckBox = checkBox,
            ActionHumanString = actionHumanString,
            DateTimeOfChange = dateTimeOfOperation
        });

        using (ApplicationContext db = new ApplicationContext())
        {
            if (actionNumber == 2 || actionNumber == 5)
            {
                Pause pause = new Pause(){wcGuid = wcGuid, Operation = operation, BoxSerial = boxSerial, SkusSerial = skusSerial, ActionNumber = actionNumber, DateTime = dateTimeOfOperation};
                db.Pauses.Add(pause);
            }
            Change change = new Change() { wcGuid = wcGuid, Operation = operation, BoxSerial = boxSerial, SkusSerial = skusSerial, ActionNumber = actionNumber, DateTime = dateTimeOfOperation };
            db.Changes.Add(change);
            db.SaveChanges();
        }

        return Ok("Request successfuly completed");
    }
}

抛出的异常信息

fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HMU4QP2AD7CS", Request id "0HMU4QP2AD7CS:00000001": An unhandled exception was thrown by the application.
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Unexpected end of request content.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1ContentLengthMessageBody.ReadAsyncInternal(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.ReadAsyncInternal(Memory`1 destination, CancellationToken cancellationToken) 
at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token) 
at System.Text.Json.Serialization.ReadBufferState.ReadFromStreamAsync(Stream utf8Json, CancellationToken cancellationToken, Boolean fillBuffer) 
at System.Text.Json.JsonSerializer.ReadFromStreamAsync[TValue](Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken) 
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) 
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) 
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext) 
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object container) 
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext() 
--- End of stack trace from previous location --- 
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) 
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) 
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) 
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) 
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) 
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) 
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) 
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

解决方案

1. 前端添加防抖逻辑

快速点击会导致前一个请求被中断,引发请求内容截断。给按钮设置300-500ms的冷却时间,避免短时间内重复发起请求:

let debounceTimer = null;
document.getElementById('yourButton').addEventListener('click', () => {
  if (debounceTimer) clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => {
    // 发起Ajax请求
    fetch('/api/change', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(yourRequestData)
    });
  }, 300); // 300ms冷却时间,可根据需求调整
});

2. 后端全局捕获该异常

在Program.cs中配置全局异常处理,捕获BadHttpRequestException并返回友好响应,避免程序崩溃:

app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        context.Response.ContentType = "application/json";
        
        var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>();
        
        if (exceptionFeature?.Error is BadHttpRequestException)
        {
            await context.Response.WriteAsJsonAsync(new 
            { 
                Message = "请求内容不完整,请稍后重试" 
            });
        }
    });
});

3. 前端控制请求并发状态

用标志位判断当前是否有请求在进行,确保上一个请求完成后再发起下一次请求:

let isRequestInProgress = false;
document.getElementById('yourButton').addEventListener('click', async () => {
  if (isRequestInProgress) return;
  isRequestInProgress = true;
  try {
    const response = await fetch('/api/change', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(yourRequestData)
    });
    // 处理响应
  } catch (error) {
    // 处理错误
  } finally {
    isRequestInProgress = false;
  }
});

4. 验证请求实体类匹配性

确认ParametrsForButton类的属性与前端发送的JSON字段完全一致,避免序列化过程中出现异常:

public class ParametrsForButton
{
    public string WcGuid { get; set; }
    public string Operation { get; set; }
    public string SkusSerial { get; set; }
    public string BoxSerial { get; set; }
    public int ActionNumber { get; set; }
    public int OperationNumber { get; set; }
    public int CheckBox { get; set; }
}

内容的提问来源于stack exchange,提问作者Alexey Burakov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:44:53