自定义控制器工厂,依赖注入/Structuremap在ASP.NET MVC中的问题

27

最近我尝试使用 StructureMap 实现依赖注入。我成功地按照示例完成了全部步骤,但每次尝试运行应用程序时,都会遇到一个抛出的异常。这里是来自我的控制器工厂的一些代码片段。

public class StructureMapControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(Type controllerType)
    {
        if (controllerType == null)
            throw new ArgumentNullException("controllerType");

        return ObjectFactory.GetInstance(controllerType) as Controller;
    }
}

我的 Global.asax 文件调用了一个静态的 BootStrapper 类来注册所有的依赖项,但是看起来 StructureMapControllerFactory 的 GetControllerInstance 方法被调用了两次。第一次调用时,正确的 controllerType 被传递进去,但第二次调用时它总是 null。

第一次调用 GetControllerInstance 时,类型被设置为 HomeController,这是正确的。HomeController 中的代码会执行并返回 View()。在返回 View() 后,aspx 文件会触发 Page_Load 事件。在跟踪代码后,它到达以下一行:

httpHandler.ProcessRequest(HttpContext.Current);

这就是第二次调用 GetControllerInstance 的地方。

下面是我 Global.asax 文件中可能相关的部分:

   protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);

        Bootstrapper.ConfigureStructureMap();

        ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
    }

我非常热衷于让依赖注入正常工作,并且如果有人能帮助我,我将不胜感激。:)


你如何注册你的控制器? - Sebastian
我认为你应该抛出一个404 http异常 - user330606
2个回答

45

更新 发生这种情况的原因是,当在CSS文件中指定了一张图片且该图片缺失时,路由框架会尝试将URL映射到一个控制器。忽略下面列出的路由可以防止出现错误,但我决定不实施它,因为这是一种通知您存在缺失资源的好方式。

您可以在此处看到使用 Structure Map 设置依赖注入的详细说明和示例。

我遇到了同样的问题,我认为我已经找到了解决方法。由于某种原因,每当您尝试提供自己的控制器工厂时,您需要添加一些额外的 IgnoreRoute 定义。首先,我会在 GetControllerInstance 方法中添加这行代码:

if(controllerType == null)
    return base.GetControllerInstance(controllerType)

这将至少为您提供更多的错误信息,以了解导致controllerType为空的请求是什么。在我的情况下,我在css文件中设置了一个背景图像,如下所示:

background: url(img/logo.gif);
所以发生的情况是路由正在寻找一个名为"img"的控制器和一个处理logo.gif或类似文件的操作。这显然不是正确的行为。
经过一番调查,我意识到需要在我的Global.asax文件中添加一个IgnoreRoute定义来忽略我站点中“content”目录中的任何内容,就像这样:
routes.IgnoreRoute("{Content}/{*pathInfo}");

我仍然不确定为什么您不需要对默认的ControllerFactory进行此操作,但无论如何它可以正常工作。

您可能会遇到与favicon.ico相同的问题。特别是如果您使用Google Chrome。您也需要添加这个:

routes.IgnoreRoute("{*favicon}", new {favicon=@"(.*/)?favicon.ico(/.*)?"})

谢谢,这可能是原因,回到家后会汇报。 - kitsune
1
我也遇到了Windsor ControllerFactory的同样问题。感谢您提供的解决方法,它非常有效。 - Robert Claypool
+1为背景:url(img / logo.gif); 我的错误是我在使用JQuery UI时没有包含图像文件。我只使用了一小部分功能,没有意识到我需要的图片 - 哎呀! - ozz
这正是我的问题。感谢您详细的回复 :-) - Lars Udengaard

4

我猜测您正在请求一个静态文件,比如一个 JavaScript 文件,但该文件可能尚未添加到您的项目中,或者对它的引用有误。您应该监视浏览器的网络请求,并查找不正确解析为静态文件的网络请求。如果您正在使用 IE,可以使用 Firebug 在 FF 或 Fiddler 进行此操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接