Model view controller SportsStore:MVC编程问题[Castle WindsorController Factory]

Model view controller SportsStore:MVC编程问题[Castle WindsorController Factory],model-view-controller,castle-windsor,Model View Controller,Castle Windsor,所以我一直在关注Steven Sanderson的书《Pro ASP.NET MVC框架》,我遇到了一个例外: No parameterless constructor defined for this object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more informa

所以我一直在关注Steven Sanderson的书《Pro ASP.NET MVC框架》,我遇到了一个例外:

No parameterless constructor defined for this object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

Source Error:

Line 16:             HttpContext.Current.RewritePath(Request.ApplicationPath, false);
Line 17:             IHttpHandler httpHandler = new MvcHttpHandler();
Line 18:             httpHandler.ProcessRequest(HttpContext.Current);
Line 19:             HttpContext.Current.RewritePath(originalPath, false);
Line 20:         }


Source File: C:\Users\Stephen\Documents\Visual Studio 2008\Projects\SportsStore\WebUI\Default.aspx.cs    Line: 18 
这是我的WindsorController工厂代码:

public class WindsorControllerFactory : DefaultControllerFactory
{
    WindsorContainer container;

    // The constructor
    // 1. Sets up a new IoC container
    // 2. Registers all components specified in web.config
    // 3. Registers all controller types as components
    public WindsorControllerFactory()
    { 
        // Instantiate a container, taking configuration from web.config
        container = new WindsorContainer(
                        new XmlInterpreter(new ConfigResource("castle"))
                    );

        // Also register all the controller types as transient
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        foreach (Type t in controllerTypes)
            container.AddComponentWithLifestyle(t.FullName, t, Castle.Core.LifestyleType.Transient);
    }

    // Constructs the controller instance needed to service each request
    protected override IController GetControllerInstance(Type controllerType)
    {
        return (IController)container.Resolve(controllerType);
    }
}
My Global.asax.cs代码:

protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory());
    }
以及web.config值:

<configSections>
    <section name="castle"
             type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
                   Castle.Windsor"/>
</configSections>
<castle>
    <properties>
      <myConnStr>Server=.\SQLEXPRESS;Database=SportsStore;Trusted_Connection=yes;</myConnStr>
    </properties>
    <components>
      <component id="ProdsRepository"
                 service="DomainModel.Abstract.IProductsRepository, DomainModel"
                 type="DomainModel.Concrete.SqlProductsRepository, DomainModel">
        <parameters>
          <connectionString>#{myConnStr}</connectionString>
        </parameters>
      </component>
    </components>
</castle>

服务器=。\SQLEXPRESS;数据库=体育商店;可信连接=是;
#{myConnStr}
谢谢大家!
-Steve

我想说的是,问题是您试图在不传递连接字符串的情况下实例化Linq to SQL DataContext

解决方案是声明如下内容:

<components>
    <component id="..." service="..." type="...">
        <parameters>
            <connectionString>blah blah blah</connectionString>
        </parameters>
    </component>
</components>
它能解决你的问题吗?

使用: 受保护的覆盖IController GetControllerInstance(System.Web.Routing.RequestContext RequestContext,类型controllerType)

代替:
受保护的重写IController GetControllerInstance(类型controllerType)

我有这个问题,当您有一个没有默认构造函数的实体类时,就会发生这个问题。始终创建一个不接受参数的默认构造函数。

命名空间WebUI
namespace WebUI
{
    public class WindsorControllerFactory:DefaultControllerFactory
    {
        WindsorContainer container;

        public WindsorControllerFactory()
        {
            container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

            container.Register(AllTypes
                .FromThisAssembly()
                .BasedOn<IController>()
                .If(Component.IsInSameNamespaceAs<Controllers.ProductsController>())
                .If(t => t.Name.EndsWith("Controller"))
                .Configure(c=>c.LifeStyle.Transient.Named(c.Implementation.Name)));
        }

        protected override IController GetControllerInstance(RequestContext ctx, Type controllerType)
        {
            if (controllerType == null) { return null; }
            return (IController)container.Resolve(controllerType);            
        }
    }
 }
{ 公共类WindsorController工厂:DefaultControllerFactory { 温莎集装箱; 公共风管控制器工厂() { 容器=新的WindsorContainer(新的XML解释器(新的配置资源(“城堡”)); 容器.寄存器(所有类型) .FromThisAssembly()中的 .BasedOn() .If(Component.IsInSameNamespaceAs()) .If(t=>t.Name.EndsWith(“控制器”)) .Configure(c=>c.lifety.Transient.Named(c.Implementation.Name)); } 受保护的重写IController GetControllerInstance(RequestContext ctx,类型controllerType) { 如果(controllerType==null){return null;} 返回(IController)容器。解析(controllerType); } } }
我只是回应一下……因为这是一个老问题(2009年)。长话短说,这与Windsor的配置值在错误的配置(视图而不是基本web.config)中有关。这解决了手头的问题。

嘿,通过调试,发现WindsorController Factory的构造函数中触发了此异常:异常详细信息:System.Configuration.ConfigurationErrorsException:在与此域关联的配置文件中找不到“castle”节。它显然在web.config中,但出于某种原因,它找不到它。我认为这是当前的问题。由于应用程序启动一次,会引发该异常,然后刷新它,因此无法加载控制器,而且由于WindsorController工厂是逻辑应该在的地方,这就是问题所在。Annnnd,我是新手!没有意识到视图文件夹和应用程序本身都有一个web.config。Castle的所有适当配置数据都在Views web.config中,而不是web应用程序的web.config中。鸡蛋在我脸上。我交换了,一切正常!你知道温莎有流畅的专用注册API,对吗?您不必使用自定义反射。
namespace WebUI
{
    public class WindsorControllerFactory:DefaultControllerFactory
    {
        WindsorContainer container;

        public WindsorControllerFactory()
        {
            container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

            container.Register(AllTypes
                .FromThisAssembly()
                .BasedOn<IController>()
                .If(Component.IsInSameNamespaceAs<Controllers.ProductsController>())
                .If(t => t.Name.EndsWith("Controller"))
                .Configure(c=>c.LifeStyle.Transient.Named(c.Implementation.Name)));
        }

        protected override IController GetControllerInstance(RequestContext ctx, Type controllerType)
        {
            if (controllerType == null) { return null; }
            return (IController)container.Resolve(controllerType);            
        }
    }
 }