【问题标题】:StructureMap controller factory and null controller instance in MVCMVC 中的 StructureMap 控制器工厂和空控制器实例
【发布时间】:2010-10-29 18:20:30
【问题描述】:

我仍在尝试使用 StructureMap 解决问题,我遇到的问题之一是当将空控制器类型传递给它时,我的 Controller Factory 类爆炸了。这只发生在应用程序第一次构建时,之后每个后续构建都可以正常工作。即使我关闭 Visual Studio 并重新打开项目(我没有在 IIS 中运行它)。几乎就像是在进行某种缓存。这是控制器类的样子:

public class IocControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(Type controllerType)
    {
        try
        {
            return (Controller)ObjectFactory.GetInstance(controllerType);
        }
        catch (StructureMapException)
        {
            System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
            throw;
        }
    }
}

可能出了什么问题?我需要注册每个控制器吗?谢谢。

【问题讨论】:

  • 传递给它的空控制器是什么意思?
  • 我的意思是控制器类型的空引用被传递给 GetControllerInstance()。我不明白的是那个空引用来自哪里。我猜 MVC 框架传递了一个空控制器实例?我最初以为它与 StructureMap 有关,但看起来并非如此。我想我可以在方法中检查 null,但我宁愿弄清楚为什么它正在做它正在做的事情。最奇怪的是,它发生在我打开项目并在重新启动后第一次在 Visual Studio 中构建它之后。之后它每次都有效。
  • 我遇到了完全相同的问题。有人对此有解决方案吗?
  • 我还没有弄清楚最初的问题主要是因为它很难调试。我必须重新启动机器并重新打开项目才能真正复制问题。我最终做的只是检查一个空控制器实例。它似乎没有破坏任何东西,但肯定有助于了解问题发生的原因。

标签: model-view-controller null controller structuremap


【解决方案1】:

大多数浏览器在您加载站点时都在寻找 favicon.ico,并且此行为可能涉及一些缓存,这可能解释了您提到的奇怪的“仅在第一次构建时失败”的事情。

在我的情况下,这导致了控制器工厂中的空控制器类型问题。

在 global.asax 中添加 routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" }); 会使错误消失,请求应该落入文件系统,而 MVC 不会在您的代码中寻找 favico.ico 控制器。

这是Gunnar Peipman post about this的链接

我通过在我的自定义控制器工厂类中覆盖 GetControllerType(string controllerName) 并检查每个请求的 controllerName 值是什么来发现的。

【讨论】:

    【解决方案2】:

    我在使用 ninject 构建的控制器工厂时遇到了同样的问题。

    当 MVC 无法解析路由表中的路由或路由指定不存在的控制器时,似乎 MVC 会将控制器类型传递给 null。我做了两件事来解决这个问题。您可能需要检查您的路由表并添加一个显示 404 错误页面的包罗万象的路由,如此处所述.Net MVC Routing Catchall not working

    您还可以使用路由调试器检查出了什么问题。 http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

    【讨论】:

    • 另一种解决方案,扩展现有控制器工厂时:检查控制器类型是否为空,如果是,则让现有工厂处理请求,而不是自己处理。
    【解决方案3】:

    我遇到了类似的问题。我相信这是对不存在的图像、CSS 文件等的 HTTP 请求。

    我们知道 MVC 路由首先查看请求的文件是否物理存在。如果没有,则 URL 将针对配置的路由进行测试。我认为对物理上不存在的图像的请求已传递给路由引擎,并且不匹配任何路由,因此使用了 NULL。

    所以要修复它,请使用FireBug 或其他需要注意的东西,并修复损坏的 HTTP 请求。在开发过程中,我使用了这样的路由来暂时绕过这些问题(我所有的资源文件夹都以下划线开头,例如_Images、_Styles 等):

    routes.IgnoreRoute("_*");  // TODO: Remove before launch
    

    希望这会有所帮助!

    【讨论】:

      【解决方案4】:

      我认为您需要做的事情与默认 MVC 控制器工厂对 GetControllerInstance 方法所做的事情完全相同。如果您查看位于http://aspnetwebstack.codeplex.com/ 的 DefaultControllerFactory 的 Microsoft 源代码,您将看到当 controllerType 为 null 时 DefaultControllerFactory 会引发 404 异常。以下是我们根据这些信息执行此操作的方法:

       public class StructureMapControllerFactory : DefaultControllerFactory
       {
            protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
            {
                 if (controllerType == null)
                      return base.GetControllerInstance(requestContext, controllerType);
                 var controller = ObjectFactory.GetInstance(controllerType);
                 return (IController)controller;
            }
       }
      

      基本上,这将确保当用户输入无效路由时,应用程序将其作为 404 错误处理。

      【讨论】:

      • 您能提供更多细节吗?我遇到了同样的问题,上面的解决方案对我不起作用(抛出 HttpException 并且我返回到调试器)。您是否覆盖了控制器工厂中的任何其他方法?你提供了构造函数吗?您是如何在 Global.asax 中注册的?即使我的自定义控制器工厂 only 调用基本实现,我仍然会收到错误。
      • 我想通了。我只是用DebuggerNonUserCodeAttribute 装饰了GetControllerInstance,现在一切正常。
      猜你喜欢
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2010-12-03
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多