20

我使用Web.api和团结,我越来越想打开默认时出现以下错误“帮助”区域:String类型不能构建

[InvalidOperationException: The type String cannot be constructed. You must configure the  container to supply this value.] 
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.GuardTypeIsNonPrimitive(IBuilderContext context, SelectedConstructor selectedConstructor) +280 
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context) +356 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260 
    Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey) +205 
    Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +231 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260 
    Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250 
    Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101 
    BuildUp_System.Web.Http.HttpRouteCollection(IBuilderContext) +202 
    Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42 
    Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +319 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260 
    Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250 
    Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101 
    BuildUp_System.Web.Http.HttpConfiguration(IBuilderContext) +202 
    Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42 
    Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +319 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260 
    Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250 
    Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101 
    BuildUp_API.Areas.HelpPage.Controllers.HelpController(IBuilderContext) +204 
    Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42 
    Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +319 
    Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260 
    Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) +373 


[ResolutionFailedException: Resolution of the dependency failed, type = "API.Areas.HelpPage.Controllers.HelpController", name = "(none)". 
Exception occurred while: while resolving. 
Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value. 
----------------------------------------------- 
At the time of the exception, the container was: 

    Resolving API.Areas.HelpPage.Controllers.HelpController,(none) 
    Resolving parameter "config" of constructor API.Areas.HelpPage.Controllers.HelpController(System.Web.Http.HttpConfiguration config) 
Resolving System.Web.Http.HttpConfiguration,(none) 
Resolving parameter "routes" of constructor System.Web.Http.HttpConfiguration(System.Web.Http.HttpRouteCollection routes) 
    Resolving System.Web.Http.HttpRouteCollection,(none) 
    Resolving parameter "virtualPathRoot" of constructor System.Web.Http.HttpRouteCollection(System.String virtualPathRoot) 
    Resolving System.String,(none) 
] 
    Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) +436 
    Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable`1 resolverOverrides) +50 
    Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) +48 
    Microsoft.Practices.Unity.UnityContainerExtensions.Resolve(IUnityContainer container, Type t, ResolverOverride[] overrides) +61 
    Unity.Mvc4.UnityDependencyResolver.GetService(Type serviceType) +140 
    System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +87 

[InvalidOperationException: An error occurred when trying to create a controller of type  'API.Areas.HelpPage.Controllers.HelpController'. Make sure that the controller has a parameterless public constructor.] 
    System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +247 
    System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +438 
    System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +226 
    System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +326 
    System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +177 
    System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 

我是新来的团结和我确定我缺少步骤(s)。 在webapiconfig.cs:

public static void Register(HttpConfiguration config) 
{ 
    config.Routes.MapHttpRoute(
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{action}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
    ); 

    //Custom formatter 
    config.Formatters.Clear(); 
    config.Formatters.Add(new JSONPFormater()); 

    config.EnableSystemDiagnosticsTracing(); 

    //Setup DI 
    Bootstrapper.Initialise(); 
} 

Bootstraper.cs(默认值)

public static class Bootstrapper 
    { 
    public static IUnityContainer Initialise() 
    { 
     var container = BuildUnityContainer(); 

     DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 

     return container; 
    } 

    private static IUnityContainer BuildUnityContainer() 
    { 
     var container = new UnityContainer(); 

     // register all your components with the container here 
     // it is NOT necessary to register your controllers 

     // e.g. container.RegisterType<ITestService, TestService>();  
     RegisterTypes(container); 

     return container; 
    } 

    public static void RegisterTypes(IUnityContainer container) 
    { 

    } 
    } 

我在一个web.config尝试 的web.config

<configSections> 
    <!-- For more information on Entity Framework configuration, visit  http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    <section name="entityFramework"  type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> 
    </configSections> 
    <connectionStrings> 
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-API-20130708152001;Integrated  Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-API-20130708152001.mdf" /> 
    <add name="<REMOVED>DBEntities" connectionString="metadata=res://*/Models.DAL.<REMOVED>.csdl|res://*/Models.DAL.<REMOVED>.ssdl|res://*/Models.DAL.<REMOVED>.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=<REMOVED>;initial catalog=<REMOVED>;persist security info=True;user id=<REMOVED>;password=<REMOVED>;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" /> 

<!--unity setting--> 
<unity> 
    <containers> 
     <types> 
      <register type="API.Areas.HelpPage.Controllers.HelpController, API"> 
       <constructor> 
        <param valu=""></param> 
      </constructor> 
      </register> 
     </types> 
    </containers> 
</unity> 

我是否在正确的方向?

感谢

更新: helpcontroller.cs:

public class HelpController : Controller 
    { 
     public HelpController() 
      : this(GlobalConfiguration.Configuration) 
     { 
     } 

     public HelpController(HttpConfiguration config) 
     { 
      Configuration = config; 
     } 

     public HttpConfiguration Configuration { get; private set; } 

     public ActionResult Index() 
     { 
      return View(Configuration.Services.GetApiExplorer().ApiDescriptions); 
     } 

     public ActionResult Api(string apiId) 
     { 
      if (!String.IsNullOrEmpty(apiId)) 
      { 
       HelpPageApiModel apiModel = Configuration.GetHelpPageApiModel(apiId); 
       if (apiModel != null) 
       { 
        return View(apiModel); 
       } 
      } 

      return View("Error"); 
     } 
    } 

网址我试图访问:HTTP://主机名:端口/帮助

+0

你在控制器上有什么? (您试图访问的构造函数和操作方法)。 –

+0

你的配置中有一个地方有一个构造函数,它接受一个字符串。 – Steven

+0

@FelipeOriani它是web.api项目的默认帮助控制器。我会更新问题以包含。该操作将是“索引” –

回答

23

由于您的代码示例,我假设你在控制器上而不是API控制器(来自web api)。

您的api控制器对构造函数HttpConfiguration有依赖性。该容器可能没有这种类型的定义,因此不知道如何解决它,并且错误消息中的string应该来自此类型作为依赖项。我建议您使用静态类GlobalConfiguration并访问Configuration属性以获取HttpConfiguration实例。你可以抽象它的属性,样品:现在

// include this namespace 
using System.Web.Http; 

public class HelpController : Controller 
{ 
    // remove the constructors... 

    // property 
    protected static HttpConfiguration Configuration 
    { 
     get { return GlobalConfiguration.Configuration; } 
    } 

    public ActionResult Index() 
    { 
     return View(this.Configuration.Services.GetApiExplorer().ApiDescriptions); 
    } 

    public ActionResult Api(string apiId) 
    { 
     if (!String.IsNullOrEmpty(apiId)) 
     { 
      HelpPageApiModel apiModel = this.Configuration.GetHelpPageApiModel(apiId); 
      if (apiModel != null) 
      { 
       return View(apiModel); 
      } 
     } 

     return View("Error"); 
    } 
} 

,如果你是在阿比控制器,你就可以直接访问this.Configuration属性,已经在ApiController(对于API控制器基类)和获得HttpConfiguration的实例。

37

我认为更好的方法是将InjectionConstructor属性添加到默认构造函数。该属性强制unity使用装饰构造函数。

例子:

public class HelpController : Controller 
{ 
    private const string ErrorViewName = "Error"; 

    [InjectionConstructor] 
    public HelpController() 
     : this(GlobalConfiguration.Configuration) 
    { 
    } 
+0

太棒了!清洁和短期解决方案。 –

+0

真的很棒,为我工作。谢谢! – Vishal

6

出现这种情况是因为统一将默认选择使用构造函数的原因的构造大多数参数绕过了默认的构造函数。

注释掉HelpController模板中存在的两个构造函数,并添加一个用于设置配置的默认构造函数。

//public HelpController() 
    // : this(GlobalConfiguration.Configuration) 
    //{ 
    //} 

    //public HelpController(HttpConfiguration config) 
    //{ 
    // Configuration = config; 
    //} 

    public HelpController() 
    { 
     Configuration = GlobalConfiguration.Configuration; 
    } 
+2

简单而明显的答案,当您将单元引入webapi项目时,大多数时候都能很好地工作。 –

2

注册的HttpConfiguration对象作为一个实例在UnityContainer也将有助于解决这个问题。
只需要在UnityContainer注册时添加以下行。

public static void RegisterTypes(IUnityContainer container) { 
    container.RegisterInstance<HttpConfiguration>(GlobalConfiguration.Configuration); 
} 

这将有助于Unity解决config参数,当调用与参数构造函数。

public HelpController(HttpConfiguration config) { 
    Configuration = config; 
} 
相关问题