2009-06-03 9 views
1

Est-il légitime que votre classe ASP.NET MVC ViewResult implémente IDisposable? Mon résultat de vue personnalisée a un membre de flux que je veux garantir est fermé une fois qu'il a été retransmis au client. Est-ce que ASP.NET MVC honore IDiposable sur les implémentations ViewResult?ASP.NET MVC ViewResult question

merci!

Répondre

2

ViewResult n'implémente pas l'interface IDisposable. Regardez ASP.NET MVC source:

ViewResult.cs:

namespace System.Web.Mvc { 
    using System; 
    using System.Globalization; 
    using System.Text; 
    using System.Web.Mvc.Resources; 

    public class ViewResult : ViewResultBase { 
... 

ViewResultBase.cs:

namespace System.Web.Mvc { 
    using System; 
    using System.Diagnostics.CodeAnalysis; 

    public abstract class ViewResultBase : ActionResult { 
... 

ActionResult.cs:

namespace System.Web.Mvc { 

    public abstract class ActionResult { 

     public abstract void ExecuteResult(ControllerContext context); 

    } 

} 

MISE À JOUR:

Si vous implémentez l'interface IDisposable dans votre classe (dérivée de ViewResult) la méthode Dispose() (IDisposable.Dispose()) ne sera pas invoquée par le framework ASP.NET MVC.

+0

Je pense que le PO demande si son ViewResult personnalisé peut implémenter IDisposable. – DSO

+0

... et si c'est le cas, si le framework MVC appellera Dispose sur celui-ci. – DSO

+0

Ceci est une faille sérieuse dans MVC! J'espère qu'ils s'en occupent. Par exemple, FileStreamResult ne disposera pas du flux qui lui est passé! – erikkallen

0

Si vous voulez ce comportement, vous pouvez l'obtenir en étendant ControllerActionInvoker. Je crois que vous pouvez faire quelque chose comme:

// warning: untested 
public class DisposableControllerActionInvoker : ContollerActionInvoker 
{ 
    public override void InvokeActionResult(
     ControllerContext controllerContext, ActionResult actionResult) 
    { 
    base.InvokeActionResult(controllerContext, actionResult); 
    var disposable = actionResult as IDisposable; 
    if(disposable != null) 
    { 
     disposable.Dispose(); 
    } 
    } 
} 

Vous aurez alors besoin d'obtenir votre ControllerActionInvoker ajouté au contrôleur, que vous pouvez faire en utilisant une usine de contrôleur personnalisé (il y a probablement une façon plus simple mais je ne suis pas familier).