The FileStreamResult class owns an IDisposable stream if it is created from the controller using a constructor that takes a Stream argument:
public FileResult MyController() { ... Stream stream = ... return File(stream, "text/plain", fileName); }
Surely this (and perhaps its ActionResult base class) should implement IDisposable ?
Of course, if all goes well, the FileStreamResult.WriteFile() method will have Stream . And when using the built-in Action Invoker ControllerActionInvoker , there seems to be little risk of throwing an Exception before this happens.
But, given the extensible MVC architecture, it seems to me that there is a possibility of situations where Exception will prevent Stream from being set when using the custom Action Invoker.
I would think that ActionResult should implement IDisposable , and Action Invokers should be required to ensure that they are located.
Is this a design flaw or is there a good reason for this?
UPDATE
From Henk Holterman the answer is:
Please note that Action Invoker was also unable to close the file, that would be soon.
I donβt understand what you are saying here - perhaps because I donβt know enough about the structure of the handler. As far as I can see, Stream is currently located within the built-in Action Invoker:
InvokeAction => InvokeActionResult => ActionResult.ExecuteResult => FileStreamResult.WriteFile
So why can't InvokeAction use a try / finally block to ensure that the IDisposable ActionResult is removed - conceptually (and probably simplified), something like:
bool InvokeAction(ControllerContext controllerContext, string actionName) { ... ActionResult actionResult; try { ... actionResult = ... call Action method ... actionResult.ExecuteResult(controllerContext); } finally { if (actionResult != null) actionResult.Dispose(); } }