2009-08-16 3 views
3

Так я следовал книга Стивена Сандерсона называется Pro ASP.NET MVC Framework, и я бегу в исключение:SportsStore: MVC программирование вопрос [Замок WindsorControllerFactory]

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 

Вот мой WindsorControllerFactory код:

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); 
    } 
} 

Мой 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> 

Спасибо всем! -Steve

+0

Вы знаете, что у Windsor есть свободный, выделенный API регистрации, верно? Вам не нужно использовать собственное отражение. –

ответ

0

Я просто отвечаю на это ... поскольку это старый вопрос (2009). Короче говоря, он имел отношение к значениям конфигурации для Windsor, которые были в неправильной конфигурации (представления, а не базовые web.config). Это решило проблему.

0

Я бы сказал, что проблема заключается в том, что вы пытаетесь создать экземпляр Linq для SQL DataContext без передачи строки соединения.

Решение было бы объявить что-то вроде:

<components> 
    <component id="..." service="..." type="..."> 
     <parameters> 
      <connectionString>blah blah blah</connectionString> 
     </parameters> 
    </component> 
</components> 

Другого варианта, один я использую в моем текущем проекте, чтобы просто создать конструктор без параметров в вашем DataContext, который будет просто вызывать конструктор который принимает строку соединения со значением по умолчанию, объявленное в качестве статической строки на самом классе:

public partial class MyDataContext 
{ 
    private static string standardConnectionString = "blah blah blah"; 

    public MyDataContext() 
      : this(standardConnectionString) {} 
} 

ли это решить проблему?

+0

Эй, Отлаживал через и увидел это исключение стрельбы в конструкторе для WindsorControllerFactory: Сведения об исключении: System.Configuration.ConfigurationErrorsException: Не удалось найти раздел «замок» в файле конфигурации, связанной с этим доменом. Это явно в web.config, но по какой-то причине он не находит его. Я думаю, что это проблема. Так как Application_Start запускается один раз, это исключение вызывается, а затем обновляя его, он не может загрузить Контроллер из-за этого, и поскольку этот WindsorControllerFactory является логикой, в этом проблема. – StephenPAdams

+0

Annnnd, я новичок! Не понял, что есть сеть.config как для папки Views, так и для самого приложения. Все соответствующие данные конфигурации для Castle были в представлении web.config, а не в web.config веб-приложения. Яйцо на лице. Я поменялся и все работает! – StephenPAdams

0

Использование: защищен переопределение IController GetControllerInstance (System.Web.Routing.RequestContext RequestContext, тип controllerType)

Insted из: защищен переназначения IController GetControllerInstance (тип controllerType)

0

Я имел эта проблема возникает, когда у вас есть класс Entity без конструктора по умолчанию. Всегда создавайте один конструктор по умолчанию, который не принимает пареметры.

1
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);    
     } 
    } 
}