我正在使用Web.api和Unity,我在尝试打开默认的“帮助”区域时收到以下错误:
[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
我是团结的新手,我确信我错过了一步。 在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="data source=<REMOVED>;initial catalog=<REMOVED>;persist security info=True;user id=<REMOVED>;password=<REMOVED>;MultipleActiveResultSets=True;App=EntityFramework"" 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");
}
}
url我正在尝试访问:http:// hostname:port / Help
答案 0 :(得分:38)
我认为更好的方法是将InjectionConstructor属性添加到默认构造函数中。此属性强制unity使用装饰的构造函数。
示例:
public class HelpController : Controller
{
private const string ErrorViewName = "Error";
[InjectionConstructor]
public HelpController()
: this(GlobalConfiguration.Configuration)
{
}
答案 1 :(得分:23)
作为您的代码示例,我假设您使用的是Controller而不是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");
}
}
现在,如果您使用的是Api Controller,您只需直接访问ApiController上已有的this.Configuration
属性(Api控制器的基类),并获取HttpConfiguration
的实例。< / p>
答案 2 :(得分:6)
发生这种情况的原因是因为Unity默认选择使用具有最多参数的构造函数,从而绕过默认构造函数。
注释掉HelpController模板中存在的两个构造函数,并添加一个设置配置的默认构造函数。
//public HelpController()
// : this(GlobalConfiguration.Configuration)
//{
//}
//public HelpController(HttpConfiguration config)
//{
// Configuration = config;
//}
public HelpController()
{
Configuration = GlobalConfiguration.Configuration;
}
答案 3 :(得分:2)
将HttpConfiguration
对象注册为UnityContainer
中的实例也有助于解决问题
只需在UnityContainer
注册时添加以添加以下行。
public static void RegisterTypes(IUnityContainer container) {
container.RegisterInstance<HttpConfiguration>(GlobalConfiguration.Configuration);
}
这将有助于Unity
在使用参数调用构造函数时解析config
参数。
public HelpController(HttpConfiguration config) {
Configuration = config;
}
答案 4 :(得分:1)
我最近在以前正在运行的代码库上发生了此错误。以下答案显示了我为纠正它所做的工作:
Adding Web API and API documentation to an existing MVC project
基本上使用参数protected
而不是public