我的項目中存在依賴項注入問題,它在實施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