2010-09-30 80 views
6

我有一个ASP.NET MVC 2应用程序与定制StructureMap控制器厂处理的依赖注入我的控制器:如何处理在ASP.NET MVC控制器工厂异常

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

我想知道如何在这个控制器工厂中处理异常,以便可以像处理具有HandleError属性的控制器那样将它们重定向到〜/ Views/Shared/Error.aspx。尽管将CustomErrors属性设置为“On”,但目前异常不会执行此操作。

目前我可以使用像“〜/ DoesNotExist/edit/1”这样的URL来产生这样的异常。使用默认路由:

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

MVC匹配此路由并将控制器名称“DoesNotExist”传递到我的控制器工厂。 GetControllerType然后返回null,并在对StructureMap的调用中导致空引用异常。然后我想能够处理这个异常。

请注意,添加后续捕获所有路由不会解决此问题 - MVC匹配默认路由。

我知道我可以通过对控制器的默认路由设置约束条件来解决此特定问题,但问题是关于如何在工厂中使用正常MVC〜/ Views/Shared/Error.aspx的更一般的问题。

请注意,我不希望答案要求控制器工厂紧密耦合到特定的MVC应用程序。理想情况下,此工厂应该位于引用程序集中,而不是在相同的解决方案中

回答

2

也许你可以改编this controller factory来处理例外。

+0

是的,谢谢你指出我 - 这是一个非常好的解决方案。 – 2010-10-07 08:32:32

0

我会创建一个错误控制器,如果它找不到请求的控制器,它将被控制器工厂调用。然后在其中重写HandleUnknownAction以捕获正在请求的任何操作。

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

是的,这样做,但这确实意味着与工厂在组装需要也包含错误控制器。这不是一场灾难,但如果可以的话,我想分开关注。 – 2010-09-30 14:19:32

+0

在我自己的项目中,我指向了主控制器,并让错误处理程序接管。不完全分离,但很可能大部分项目都会有一个HomeController。 – Clicktricity 2010-09-30 14:22:00

+0

不错,是的这是一个非常安全的公约 – 2010-09-30 15:32:40