[英]When to dispose of a HttpResponseMessage or a HttpContent
I'm setting up an API to interact with a database and when the api receives a post to create an entry that is already present on it's respective table I want to return a code 209 Conflict with an explanatory message. 我正在设置一个API来与数据库进行交互,当api收到一个帖子来创建一个已经存在于其各自表中的条目时,我想返回一个代码209与一条解释性消息冲突。 So I tried this: 所以我尝试了这个:
Controller 调节器
public async Task<IHttpActionResult> PostOrganizationAsync(Organization organization)
{
using (var context = new ContextHandler())
{
bool added = await context.AddOrganizationAsync(organization);
if (added)
{
return Ok();
}
else
{
using (var httpContent = new StringContent("An organization with this Id already exists on the database"))
{
return new CustomHttpResponse(HttpStatusCode.Conflict, httpContent);
}
}
}
}
ContextHandler ContextHandler中
class ContextHandler : IDisposable
{
static AuditLogsEntities LogDatabaseContext;
public ContextHandler()
{
LogDatabaseContext = new AuditLogsEntities();
LogDatabaseContext.Configuration.LazyLoadingEnabled = false;
}
public void Dispose()
{
LogDatabaseContext.Dispose();
}
public async Task<bool> AddOrganizationAsync(Organization organization)
{
var findOrg = await LogDatabaseContext.OrganizationSet.FindAsync(organization.Id);
if (findOrg != null)
{
return false;
}
else
{
LogDatabaseContext.OrganizationSet.Add(organization);
await LogDatabaseContext.SaveChangesAsync();
return true;
}
}
}
CustomHttpResponse CustomHttpResponse
public class CustomHttpResponse : IHttpActionResult
{
public HttpStatusCode StatusCode;
public HttpContent Content;
public CustomHttpResponse(HttpStatusCode httpStatusCode, HttpContent httpContent)
{
StatusCode = httpStatusCode;
Content = httpContent;
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
HttpResponseMessage httpResponse = null;
using (httpResponse = new HttpResponseMessage(StatusCode))
{
httpResponse.Content = Content;
return httpResponse;
}
}
}
Posting a new valid entry works fine, but trying to post an already existing one to test the 209 response results in an ObjectDisposedException
, which I assume happens because of one of my using
blocks, but the issue is I'm not sure which block it is and why it would result in an error. 发布一个新的有效条目工作正常,但尝试发布一个已经存在的条目来测试209响应导致一个ObjectDisposedException
,我认为这是因为我的一个using
块发生,但问题是我不确定是哪个阻止它是为什么会导致错误。
EDIT: I somehow only now realized that according to the StackTrace, the exception is thrown when the private HttpRequestMessage _request
property is being set inside HttpResponseMessage
编辑:我不知何故现在才意识到,根据StackTrace,当在HttpResponseMessage
中设置private HttpRequestMessage _request
属性时抛出异常
Don't use using blocks. 不要使用块。 Just store them in a private variable and dispose of them with the controller disposal. 只需将它们存储在一个私有变量中,并通过控制器处理它们进行处理。 Also, you can use Task.FromResult for already completed tasks. 此外,您可以使用Task.FromResult完成已完成的任务。
Controller 调节器
private StringContent _httpContent
private CustomHttpResponse _customHttpResponse
public async Task<IHttpActionResult> PostOrganizationAsync(Organization organization)
{
using (var context = new ContextHandler())
{
bool added = await context.AddOrganizationAsync(organization);
if (added)
{
return Ok();
}
else
{
this._httpContent = new StringContent("An organization with this Id already exists on the database"))
this._customHttpResponse = new CustomHttpResponse(HttpStatusCode.Conflict, httpContent);
return this._customHttpResponse;
}
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (this._httpContent != null)
{
this._httpContent.Dispose();
}
if (this._customHttpResponse != null)
{
this._customHttpResponse.Dispose();
}
}
}
CustomHttpResponse CustomHttpResponse
public class CustomHttpResponse : IHttpActionResult
{
public HttpStatusCode StatusCode;
public HttpContent Content;
public CustomHttpResponse(HttpStatusCode httpStatusCode, HttpContent httpContent)
{
StatusCode = httpStatusCode;
Content = httpContent;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage httpResponse = new HttpResponseMessage(StatusCode);
httpResponse.Content = Content;
return Task.FromResult(httpResponse);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.