Asp.net-Web-Api

無法構造類型 String

  • August 22, 2013

我正在使用 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");
       }
   }

我正在嘗試訪問的網址:http://hostname:port/Help

作為您的程式碼範例,我假設您使用的是控制器而不是 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 上,您只需直接訪問this.ConfigurationApiController(Api 控制器的基類)上已有的屬性並獲取HttpConfiguration.

我認為更好的方法是將 InjectionConstructor 屬性添加到預設建構子中。此屬性強制統一使用修飾的建構子。

例子:

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

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

引用自:https://stackoverflow.com/questions/18389309