You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

HttpResponseMessage/HttpContent何时释放?API返回209 Conflict实现咨询

我来帮你搞定这两个问题:

何时释放HttpResponseMessage或HttpContent对象?

核心原则就是谁创建谁负责,框架托管的不用管

  • 如果你是手动new出来HttpResponseMessageHttpContent,而且没有把它交给Web API框架处理(比如没通过return返回给客户端),那必须手动释放——要么用using语句包裹,要么调用.Dispose()方法。比如你临时创建了一个StringContent生成测试数据,用完就得释放它。
  • 要是你用的是Web API内置的响应方法(比如Ok()BadRequest()NotFound()),这些方法返回的IHttpActionResult对应的响应对象,生命周期完全由框架管理,你根本不用操心释放的事。
  • 另外,如果把你自己创建的HttpContent附加到了会被框架托管的HttpResponseMessage上(比如创建了HttpResponseMessage然后通过ResponseMessage()返回),框架也会顺带帮你释放这个HttpContent,不用单独处理。
如何在Web API中返回209 Conflict状态码?

先提个重要提醒:标准HTTP 1.1规范里,代表「资源冲突」的状态码其实是409 Conflict,209是WebDAV扩展定义的特殊状态码,一般只在WebDAV场景下使用。如果你的API是常规REST接口,更推荐用409,这样客户端兼容性更好。不过既然你明确要返回209,给你两种实现方式:

方式一:直接返回自定义HttpResponseMessage

这是最直接的写法,不用额外封装:

public async Task<IHttpActionResult> PostOrganizationAsync(Organization organization)
{
    using (var context = new ContextHandler())
    {
        bool added = await context.AddOrganizationAsync(organization);
        if (added)
        {
            return Ok();
        }
        else
        {
            // 创建209状态码的响应
            var response = new HttpResponseMessage((HttpStatusCode)209)
            {
                Content = new StringContent("该组织条目已存在于数据库中"),
                ReasonPhrase = "Conflict"
            };
            // 通过ResponseMessage交给框架处理,框架会负责释放资源
            return ResponseMessage(response);
        }
    }
}

⚠️ 注意:这里不要给HttpResponseMessageusing,不然框架拿到的时候它已经被释放了,会抛出异常。

方式二:自定义IHttpActionResult(适合重复使用)

如果你的API多个地方都要返回209,可以封装一个自定义的ActionResult,用起来更优雅:

// 自定义209 Conflict的ActionResult
public class Conflict209Result : IHttpActionResult
{
    private readonly string _message;
    private readonly HttpRequestMessage _request;

    public Conflict209Result(string message, HttpRequestMessage request)
    {
        _message = message;
        _request = request;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage((HttpStatusCode)209)
        {
            Content = new StringContent(_message),
            RequestMessage = _request,
            ReasonPhrase = "Conflict"
        };
        return Task.FromResult(response);
    }
}

然后在Controller里直接用:

else
{
    return new Conflict209Result("该组织条目已存在于数据库中", Request);
}

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

火山引擎 最新活动