我已经看到了很多关于不正确使用依赖注入会导致错误的答案。。。
尝试创建"FranchiseUserController"类型的控制器时出错。请确保控制器具有无参数的公共构造函数。
但我没有使用任何依赖注入产品,如Ninject、Unity等。此外,这个错误在我的本地开发环境中不会发生,但当我们在QA服务器上进行测试时就会出现。此外,它会间歇性地发生,并且它与我的几个Web API方法一起发生。它发生在多个用户和多个浏览器中。
我甚至不确定在这里发布什么代码。如果你需要更多信息,请告诉我,我很乐意发布。
这是一个使用AngularJS的ASP.NET MVC/WebAPI应用程序。从Angular客户端调用Web API控制器时发生错误。angular应用程序在错误回调中接收到一个500内部服务器错误的响应。。。
数据异常消息:尝试创建"特许用户控制器"类型的控制器时出错。请确保控制器具有无参数的公共构造函数。数据异常类型:System.InvalidOperationException
这是错误中提到的控制器的构造函数和被调用的方法。
构造函数
public FranchiseUserController()
{
_sm = new SettingManager();
_millicare_connectionString = _sm.conn_MilliCareSvcConnectionString();
_maa_connectionString = _sm.conn_MaaSvcConnectionString();
if (AppConstants.OverrideSecurityLocal && _sm.ServiceConfiguration() == ServiceConfigurationValues.LOCAL)
{
_acsUser.Name = Environment.UserName;
_acsUser.MaaUserGuid = _sm.developerAdGuid().ConvertAdGuidToMaaGuid();
_acsUser.Role = _sm.app_TestUserRole();
}
else {
ClaimsPrincipal userClaims = (ClaimsPrincipal)this.User;
_acsUser.Name = ((ClaimsIdentity)userClaims.Identity).FindFirst(MiddlewareClaimTypes.Name).Value;
_acsUser.MaaUserGuid = ((ClaimsIdentity)userClaims.Identity).FindFirst(MiddlewareClaimTypes.MaaUserGuid).Value;
_acsUser.Role = AppConstants.RoleNotAuthorized;
//Get user role
if (ApplicationMiddleware.Security.Extensions.HasClaim(userClaims, AppConstants.Maint_Option, AppConstants.Maint_Action, AppConstants.Maint_SecureValue_Approver, _sm.acs_MAAFranchiseResourceMaint()))
{
_acsUser.Role = AppConstants.RoleApprover;
}
else if (ApplicationMiddleware.Security.Extensions.HasClaim(userClaims, AppConstants.Maint_Option, AppConstants.Maint_Action, AppConstants.Maint_SecureValue_Admin, _sm.acs_MAAFranchiseResourceMaint()))
{
_acsUser.Role = AppConstants.RoleAdmin;
}
else if (ApplicationMiddleware.Security.Extensions.HasClaim(userClaims, AppConstants.Resource_Option, AppConstants.Resource_Action, AppConstants.Resource_SecureValue_Franchise, _sm.acs_MAAFranchiseResourceReports()))
{
_acsUser.Role = AppConstants.RoleFranchise;
}
}
}
以及方法
[ValidateCustomAntiForgeryToken]
[HttpPost]
public HttpResponseMessage UpdateAddress(Address_dto Value)
{
HttpResponseMessage srvresponse = new HttpResponseMessage();
if (_acsUser.Role == AppConstants.RoleAdmin || _acsUser.Role == AppConstants.RoleApprover)
{
Value.modified_user = _acsUser.Name;
srvresponse = WrapServiceCall<string>((serviceResult, responseMessage) =>
{
MilliCareSvcClient().Using(svc =>
{
serviceResult.OperationSuccessful = svc.UpdateAddress(Value);
});
});
return srvresponse;
}
else
{
var noaccessServiceResult = new ServiceResult<string>();
noaccessServiceResult.SetUnauthorizedMessage();
srvresponse.Content = new ObjectContent<ServiceResult<string>>(noaccessServiceResult, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
return srvresponse;
}
//});
}
很可能,您的控制器构造函数中有以某种方式访问HttpControllerContext
的代码。在创建控制器之前(可能是在应用程序池重新启动期间),您可能会遇到HttpControllerContext
尚未就绪的情况。
最好让控制器构造函数保持简单,因为它们可以在应用程序生命周期的任何时候创建。如果您使用DI,我建议您将复杂的逻辑移动到服务中,并且除了分配服务之外,不要在构造函数中做任何事情。但是,由于您没有使用DI,您可以通过将逻辑移动到控制器的Initialize
事件中,并完全删除构造函数来解决此问题。
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
_sm = new SettingManager();
_millicare_connectionString = _sm.conn_MilliCareSvcConnectionString();
_maa_connectionString = _sm.conn_MaaSvcConnectionString();
if (AppConstants.OverrideSecurityLocal && _sm.ServiceConfiguration() == ServiceConfigurationValues.LOCAL)
{
_acsUser.Name = Environment.UserName;
_acsUser.MaaUserGuid = _sm.developerAdGuid().ConvertAdGuidToMaaGuid();
_acsUser.Role = _sm.app_TestUserRole();
}
else
{
ClaimsPrincipal userClaims = (ClaimsPrincipal)this.User;
_acsUser.Name = ((ClaimsIdentity)userClaims.Identity).FindFirst(MiddlewareClaimTypes.Name).Value;
_acsUser.MaaUserGuid = ((ClaimsIdentity)userClaims.Identity).FindFirst(MiddlewareClaimTypes.MaaUserGuid).Value;
_acsUser.Role = AppConstants.RoleNotAuthorized;
//Get user role
if (ApplicationMiddleware.Security.Extensions.HasClaim(userClaims, AppConstants.Maint_Option, AppConstants.Maint_Action, AppConstants.Maint_SecureValue_Approver, _sm.acs_MAAFranchiseResourceMaint()))
{
_acsUser.Role = AppConstants.RoleApprover;
}
else if (ApplicationMiddleware.Security.Extensions.HasClaim(userClaims, AppConstants.Maint_Option, AppConstants.Maint_Action, AppConstants.Maint_SecureValue_Admin, _sm.acs_MAAFranchiseResourceMaint()))
{
_acsUser.Role = AppConstants.RoleAdmin;
}
else if (ApplicationMiddleware.Security.Extensions.HasClaim(userClaims, AppConstants.Resource_Option, AppConstants.Resource_Action, AppConstants.Resource_SecureValue_Franchise, _sm.acs_MAAFranchiseResourceReports()))
{
_acsUser.Role = AppConstants.RoleFranchise;
}
}
}
注意:我不能肯定这就是您的应用程序中正在发生的事情,但是您应该始终假设在实例化控制器时没有可用的HTTP上下文。
顺便说一句,这种逻辑看起来像是一个贯穿各领域的问题。你应该在一个过滤器中进行,而不是在每个控制器中重复。