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

C# Web API 2.0 POST请求始终Pending,返回204则正常求排查

问题分析:Web API返回Ok(newItem)时请求Pending,返回204正常的原因及解决办法

我帮你排查了下,这个问题的核心原因出在EF实体的序列化环节,具体来说是循环引用或者延迟加载导致序列化卡住,使得响应一直无法生成完成,所以请求一直处于Pending状态;而返回204 No Content时没有响应体,不需要序列化,自然就能正常结束请求。

具体原因拆解:

看你的代码,POST接口里return Ok(newItem)返回的是TeamnewsView这个EF实体对象(来自DWP.Data.Model),而ASP.NET Web API默认用JSON.NET序列化响应内容。如果这个实体有导航属性(比如关联了NewsItem之类的其他实体),或者EF的延迟加载是开启状态的话:

  • 序列化器在处理实体时,会自动尝试访问所有可访问的属性,包括导航属性
  • 如果导航属性又反向关联回TeamnewsView,就会形成循环引用(比如TeamnewsView -> NewsItem -> TeamnewsView -> ...),JSON.NET会陷入无限循环,一直无法完成序列化
  • 即使没有循环引用,延迟加载也会触发EF去数据库加载关联数据,这个过程如果卡住或者耗时过长,也会导致响应迟迟无法返回

而返回204状态码时,API不需要返回任何响应体,跳过了序列化步骤,所以请求能正常走完整个流程。

解决方案(按推荐程度排序):

1. 改用ViewModel返回(最推荐,和你的Get方法保持一致)

就像你在Get接口里做的那样,不要直接返回EF实体,而是映射到TeamnewsViewsViewModel后再返回。这样既能避免序列化问题,也能控制返回给前端的字段,符合前后端分离的最佳实践。

修改你的Post接口代码:

[HttpPost]
[ActionName("Increment")]
public IHttpActionResult Post(string teamnewsItemId)
{
    if (teamnewsItemId == "")
    {
        return BadRequest("The newsitem Id is invalid");
    }

    var teamNewsItem = _teamnewsViewsService.GetTeamnewsView(teamnewsItemId);
    if (teamNewsItem == null)
    {
        return NotFound();
    }

    var newItem = _teamnewsViewsService.IncrementViewCount(teamNewsItem);
    
    // 把EF实体映射到ViewModel
    var viewModel = new TeamnewsViewsViewModel
    {
        Id = newItem.Id,
        TenantId = newItem.TenantId,
        NewsItemId = newItem.NewsItemId,
        ViewCount = newItem.ViewCount
    };

    return Ok(viewModel);
}

2. 关闭EF的延迟加载和代理创建

如果你暂时不想改用ViewModel,可以在你的DbContext构造函数里关闭延迟加载和动态代理,这样实体不会包含导航属性的代理对象,序列化时就不会触发额外的数据库查询或循环引用:

public class YourDbContext : DbContext
{
    public YourDbContext()
    {
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
    }
    // ...其他DbSet和配置
}

3. 配置JSON.NET忽略循环引用

在WebApiConfig.cs里配置JSON.NET忽略循环引用,这样序列化器遇到循环引用时会跳过,不会无限循环:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // ...其他路由配置
        config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    }
}

不过这种方法可能会导致部分关联属性被意外忽略,不如ViewModel的方式可控。

验证:

修改后再测试POST接口,应该就能正常返回响应,不会再出现Pending的情况了。

内容的提问来源于stack exchange,提问作者Rodney Wormsbecher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:52:26