我的项目中存在依赖项注入问题,它在实施Owin之前工作正常。在我添加Owin并开始启动课程后,问题开始出现。这个问题已经有很多文档了。但我似乎无法使用其他任何关于此事的帖子来解决它。添加Owin后,依赖注入破坏,没有为此对象定义的无参数构造函数
所涉及的服务确实具有无参数构造函数,控制器也有一个,服务保持空白。
我使用下列程序包:
- 统一(v3.5.1404)
- Unity.WebApi.5.1(V5.2.0)
- Microsoft.AspNet.SignalR.Owin(V1.2.2 )
- Microsoft.AspNet.WebApi.Owin(v5.2.3)
- Microsoft.AspNet.WebApi.OwinSelfHost(v5.2.3)
- Microsoft.Owin(V3.0.1)
- Microsoft.Owin.Security(V1.0.0)
- Microsoft.Owin.Host.SystemWeb(V3.0.1)
- Owin(V1.0.0)
- Microsoft.Owin.Host.SystemWeb(V3.0.1 )
每当我浏览到需要依赖注入的控制器时,都会发生以下错误。
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +119
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +11
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55
[InvalidOperationException: An error occurred when trying to create a controller of type '_Servicebus.Controllers.AuthenticationController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +178
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +76
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +88
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +194
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
我相信它与Global.asax.cs和Startup.cs有关。
的Global.asax.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Timers;
using Microsoft.Practices.Unity;
using BusinessLayer.HourRegistration.Services;
using BusinessLayer.HourRegistration.Interfaces;
using DataAccessLayer.HourRegistration.Repositories;
using DataAccessLayer.HourRegistration.Entities;
using System.Data.Entity;
using System.IO;
namespace Servicebus
{
public class WebApiApplication : System.Web.HttpApplication
{
Timer timer;
bool firsttime;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
/*firsttime = true;
timer = new Timer();
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Interval = 20000;
timer.AutoReset = false;
timer.Start();*/
}
private ICrmUserFilterRepository uService
{
get
{
return GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(ICrmUserFilterRepository)) as ICrmUserFilterRepository;
}
}
private IHourRegistrationService hService
{
get
{
return GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IHourRegistrationService)) as IHourRegistrationService;
}
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (firsttime)
{
firsttime = false;
timer.Stop();
List<CrmUserFilter> tempList = uService.GetAll().ToList();
hService.setFourWeeksOldClosed();
CrmFetchXml.getCrmFetchXmlInstance.reload24HoursCache(tempList);
timer.Interval = GetTimeUntilNextCacheRefresh(2);
timer.Start();
}
else {
timer.Stop();
List<CrmUserFilter> tempList = uService.GetAll().ToList();
hService.setFourWeeksOldClosed();
CrmFetchXml.getCrmFetchXmlInstance.reload24HoursCache(tempList);
timer.Interval = GetTimeUntilNextCacheRefresh(2);
timer.Start();
}
}
public static double GetTimeUntilNextCacheRefresh(int hour)
{
var currentTime = DateTime.Now;
var desiredTime = new DateTime(DateTime.Now.Year,
DateTime.Now.Month, DateTime.Now.Day, hour, 0, 0);
var timeDifference = (currentTime - desiredTime);
var timePeriod = currentTime.Hour >= hour ?
(desiredTime.AddDays(1) - currentTime) :
-timeDifference;
return Convert.ToInt32(timePeriod.TotalMilliseconds);
}
}
}
Startup.cs:
using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Practices.Unity;
using Owin;
using System.Security.Claims;
using System.Web.Helpers;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Unity.WebApi;
[assembly: OwinStartup(typeof(Servicebus.App_Start.Startup))]
namespace Servicebus.App_Start
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
//unity fix
HttpConfiguration config = new HttpConfiguration();
UnityContainer container = WebApiConfig.Register(config);
// ... Configure you web api routes
config.DependencyResolver = new UnityDependencyResolver(container);
app.UseWebApi(config);
//GlobalConfiguration.Configure(config);
//app.UseWebApi(GlobalConfiguration.DefaultServer);
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Authentication/Login")
});
//app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
}
WebApiConfig.cs:
using System.Web.Http;
using Microsoft.Practices.Unity;
using BusinessLayer.HourRegistration.Interfaces;
using BusinessLayer.HourRegistration.Services;
using DataAccessLayer.HourRegistration.Repositories;
using System.Net.Http.Formatting;
using System.Data.Entity;
using Unity.WebApi;
using System.Web.Mvc;
using Servicebus.Security;
using System.Diagnostics;
using BusinessLayer.MTO.Interfaces;
using DataAccessLayer.MTO.Repositories.InterfaceRepositories;
using BusinessLayer.MTO.Services;
using DataAccessLayer.MTO.Repositories;
using DataAccessLayer.Common.DatabaseFactory;
using DataAccessLayer.HourRegistration.UnitOfWork;
using DataAccessLayer.MTO.UnitOfWork;
namespace Servicebus
{
public static class WebApiConfig
{
public static UnityContainer Register(HttpConfiguration config)
{
config.EnableCors();
UnityContainer container = new UnityContainer();
container.RegisterType<IAuthenticationService, AuthenticationService>();
container.RegisterType<IDatabaseFactory, DatabaseFactory>(new PerResolveLifetimeManager());
container.RegisterType<IUnitOfWorkHourregistration, UnitOfWorkHourregistration>();
container.RegisterType<ICrmProjectRepository, CrmProjectRepository>();
container.RegisterType<ICrmOrderRepository, CrmOrderRepository>();
container.RegisterType<IHourRegistrationRepository, HourRegistrationRepository>();
container.RegisterType<IOverTimeHoursRepository, OverTimeHoursRepository>();
container.RegisterType<IWorkhoursRepository, WorkHoursRepository>();
container.RegisterType<IRoleRepository, RoleRepository>();
container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<IHourRegistrationService, HourRegistrationService>();
container.RegisterType<IRoleProviderService, RoleProviderService>();
container.RegisterType<ICrmUserFilterRepository, CrmUserFilterRepository>();
//for MTO
container.RegisterType<IMTOService, MTOService>();
container.RegisterType<IUnitOfWorkMTO, UnitOfWorkMTO>();
container.RegisterType<IMtoRepository, MtoRepository>();
container.RegisterType<IChapterRepository, ChapterRepository>();
container.RegisterType<IQuestionRepository, QuestionRepository>();
container.RegisterType<IQuestionKindRepository, QuestionKindRepository>();
container.RegisterType<IAnswerRepository, AnswerRepository>();
container.RegisterType<IDepartmentRepository, DepartmentRepository>();
container.RegisterType<IReportRepository, ReportRepository>();
container.RegisterType<IActionPointRepository, ActionPointRepository>();
container.RegisterType<IUserMtoRepository, UserMtoRepository>();
container.RegisterType<IRoleMtoRepository, RoleMtoRepository>();
container.RegisterType<IMtoUserResponseRepository, MtoUserResponseRepository>();
config.DependencyResolver = new UnityDependencyResolver(container);
config.Formatters.JsonFormatter.MediaTypeMappings.Add(new UriPathExtensionMapping("json", "application/json"));
config.Formatters.XmlFormatter.MediaTypeMappings.Add(new UriPathExtensionMapping("xml", "application/xml"));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "Api UriPathExtension",
routeTemplate: "api/{controller}.{ext}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "MtoApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { controller = "mto", id = RouteParameter.Optional }
);
return container;
}
}
}
确实涉及到的服务确实有一个参数的构造函数中,控制器也有一个,服务保持空白。
随机[未完成]服务:
using BusinessLayer.Authentication.Interfaces;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLayer.Authentication.Services
{
public class AuthenticationService : IAuthenticationService
{
public AuthenticationService()
{ }
public bool CheckRedirects(string applicationName, string jsonString)
{
JObject jsonObj = JObject.Parse(jsonString);
////Exists? --> Search in JSON.
foreach (KeyValuePair<string, JToken> sub_obj in (JObject)jsonObj["Redirects"])
{
}
return true;
}
}
}
AuthenticationController.cs:
using BusinessLayer.Authentication.Interfaces;
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Cors;
using System.Web.Mvc;
namespace Servicebus.Controllers
{
[System.Web.Mvc.AllowAnonymous]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class AuthenticationController : Controller
{
/// <summary>
/// Service from the business layer to get the right information
/// </summary>
public IAuthenticationService aService;
/// <summary>
/// Constructor of the hourregistation controller gets the service from the unity container.
/// </summary>
public AuthenticationController(IAuthenticationService aService)
{
this.aService = aService;
}
public ActionResult Login()
{
NameValueCollection queryString = Request.QueryString;
aService.CheckRedirects(queryString["applicationType"], System.IO.File.ReadAllText(Server.MapPath(Url.Content("~/Content/loginRedirects.json"))));
String state = Guid.NewGuid().ToString();
String url = this.Url.Action("Callback", "Authentication", null, this.Request.Url.Scheme).ToString();
return Redirect(removed);
}
public ActionResult Callback()
{
NameValueCollection queryString = Request.QueryString;
if (!queryString["code"].Equals(null))
{
IdentityStore(queryString["code"], queryString["state"]);
}
return null;
}
private void IdentityStore(string authToken, string queryString, bool isPersistent = false)
{
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, authToken));
claims.Add(new Claim("state", queryString));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties()
{
AllowRefresh = true,
IsPersistent = isPersistent,
ExpiresUtc = DateTime.UtcNow.AddDays(7)
}, identity);
}
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
public void IdentitySignout()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);
}
}
}
任何帮助理解。
问候!
我现在完全删除在Global.asax你有OWIN启动。但基本上,您需要确保所有依赖项都在OWIN启动类中注册,因为在使用OWIN服务器启动时不会使用全局... –
显示“AuthenticationController”的构造函数抛出异常的地方。 – Nkosi
我试图完全删除它,但问题依然存在。所以我决定再次添加它。无论global.asax是否存在,错误似乎都是相同的。 – InSum