2010-09-30 9 views
6

J'ai une application ASP.NET MVC 2 avec une usine de contrôleur de StructureMap personnalisé pour gérer l'injection de dépendance pour mes contrôleurs:Comment puis-je gérer une exception dans un contrôleur ASP.NET MVC usine

public class StructureMapControllerFactory : DefaultControllerFactory 
{ 
    public override IController CreateController(RequestContext context, string controllerName) 
    { 
     Type controllerType = base.GetControllerType(context, controllerName); 
     return ObjectFactory.GetInstance(controllerType) as IController; 
    } 
} 

Je voudrais pour savoir comment je peux gérer les exceptions dans cette fabrique de contrôleurs afin qu'elles puissent être redirigées vers ~/Views/Shared/Error.aspx de la même manière qu'elles le sont dans un contrôleur qui a l'attribut HandleError. Actuellement, les exceptions ne le font pas même si l'attribut CustomErrors est défini sur "On". Pour l'instant je peux générer une telle exception en utilisant une URL comme "~/DoesNotExist/edit/1". Avec la route par défaut:

routes.MapRoute(
    "Default", // Route name 
    "{controller}/{action}/{id}", // URL with parameters 
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
); 

MVC correspond à cette route et transmet le nom de contrôleur "DoesNotExist" à ma fabrique de contrôleurs. GetControllerType renvoie ensuite null et provoque une exception de référence null dans l'appel à StructureMap. Je voudrais ensuite pouvoir gérer cette exception.

Notez que l'ajout d'une capture ultérieure à toutes les routes ne résoudra pas ce problème - MVC correspond à l'itinéraire par défaut. Je sais que je pourrais résoudre ce problème particulier en mettant des contraintes sur la route par défaut pour le contrôleur, mais la question est plus générale sur la façon dont je peux utiliser le normal MVC ~/Views/Shared/Error.aspx en usine.

Notez que je ne veux pas que la réponse nécessite un couplage étroit de la fabrique du contrôleur à l'application MVC particulière. Idéalement, cette usine devrait être dans un ensemble référencé pas dans la même solution.

Répondre

2

Vous pouvez peut-être adapter this controller factory pour gérer les exceptions.

+0

Oui, merci de m'avoir indiqué - une très bonne solution au problème. –

0

Je créer un contrôleur d'erreur qui est appelé par la fabrique du contrôleur s'il ne trouve pas le contrôleur demandé. Dans ce cas, remplacez HandleUnknownAction pour capturer l'action demandée.

public class StructureMapControllerFactory : DefaultControllerFactory 
{ 
    public override IController CreateController(RequestContext context, string controllerName) 
    { 
     Type controllerType = base.GetControllerType(context, controllerName); 

     if (controllerType == null) 
      return ObjectFactory.GetInstance(ErrorController) as IController; 
     else 
      return ObjectFactory.GetInstance(controllerType) as IController; 
    } 
} 
+0

Oui, ce serait le cas, bien que cela signifie que l'assemblage avec l'usine doit également contenir le contrôleur d'erreur. Ce n'est pas un désastre mais j'aimerais séparer les préoccupations si je le peux. –

+0

Dans mes propres projets, je pointe vers le contrôleur Home et laisse le gestionnaire d'erreurs prendre le relais. Pas entièrement séparé, mais probablement que la plupart de vos projets auront un HomeController. – Clicktricity

+0

Bien, oui c'est une convention assez sûre –