8

I have this code within a request handling method of an ApiController:

if (uri != null)
{
    HttpResponseMessage r = Request.CreateResponse(HttpStatusCode.Redirect);
    r.Headers.Location = uri;
    throw new HttpResponseException(r);
}

The potential problem is that "r" is never disposed (in my code at least).
I could wrap this in a using, but then wouldn't "r" get disposed before the response is streamed to the client?

What is the correct way to handle this?

Pascalz
  • 2,348
  • 1
  • 24
  • 25
noctonura
  • 12,763
  • 10
  • 52
  • 85
  • 2
    It's interesting that they would structure their class this way. I couldn't find anything helpful in the docs, but can you just use [this constructor](http://msdn.microsoft.com/en-us/library/hh835324(v=vs.118).aspx) which takes a status code instead? – Ed S. Dec 19 '13 at 18:31
  • "wouldn't 'r' get disposed too early?" Too early for what, exactly? – spender Dec 19 '13 at 18:43
  • 2
    @spender, I think the OP is stating it would get disposed before the response could be streamed to the client. – Mike Perrenoud Dec 19 '13 at 18:45
  • Spender and Michael - thanks! I updated the question to be more clear. – noctonura Dec 19 '13 at 18:47

2 Answers2

5

All the examples I've seen show that you do not have to dispose of the Response.

public Product GetProduct(int id)
{
  Product item = repository.Get(id);
  if (item == null)
  {
    var resp = new HttpResponseMessage(HttpStatusCode.NotFound)
    {
      Content = new StringContent(string.Format("No product with ID = {0}", id)),
      ReasonPhrase = "Product ID Not Found"
    }
    throw new HttpResponseException(resp);
  }
  return item;
}

Looking at the source code to HttpResponseException, it appears that it populates a Property (HttpResponseMessage Response) with that value and disposing of it would probably cause the HttpResponseMessage either cause an ObjectDisposedException or fail to be delivered to the client.

You'll also notice that in the source code there is a SupressMessage:

 [SuppressMessage("Microsoft.Reliability", 
  "CA2000:Dispose objects before losing scope", 
  Justification = "Instance is disposed elsewhere")]

Instance is disposed of elsewhere (this is not referring to HttpResponseMesssage, it does not implement IDisposable).

What is the correct way to handle this?

I don't believe any change to your code is required.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
2

For me, "Instance is disposed elsewhere" doesn't means you don't need to deal with it.

My solution is RegisterForDispose so it becomes:

HttpResponseMessage r = Request.CreateResponse(HttpStatusCode.Redirect);
r.Headers.Location = uri;
this.request.RegisterForDispose(r);
throw new HttpResponseException(r);
ChrisTorng
  • 742
  • 7
  • 18