I've seen lots of answers about how improper use of dependency injection can cause the error...
我看到了很多关于不恰当使用依赖项注入会导致错误的答案……
An error occurred when trying to create a controller of type 'FranchiseUserController'. Make sure that the controller has a parameterless public constructor.
试图创建类型“加盟usercontroller”的控制器时发生错误。确保控制器有一个无参数的公共构造函数。
but I am not using any dependency injection products like Ninject, Unity, etc. Also, this error does not happen in my local development environment, but is showing up when we are testing on our QA server. Furthermore, it occurs intermittently and it occurs with several of my Web API methods. It occurs with multiple users and with multiple browsers.
但是我没有使用任何依赖注入产品,比如Ninject、Unity等等。此外,这个错误不会发生在我的本地开发环境中,而是在QA服务器上测试时出现。此外,它间歇性地发生,并与我的几个Web API方法一起发生。它发生在多个用户和多个浏览器中。
I'm not sure what code to even post here. Let me know if you need more information and I will be glad to post it.
我不确定在这里发布什么代码。如果您需要更多的信息,请告诉我,我很乐意发布。
This is an ASP.NET MVC / WebAPI application using AngularJS. The error occurs when calling the Web API controller from an Angular client. The angular app is receiving a response in the Error callback with a 500 Internal Server Error with...
这是一个ASP。使用AngularJS的NET MVC / WebAPI应用程序。当从角客户机调用Web API控制器时发生错误。角应用程序在错误回调中接收到一个有500个内部服务器错误的响应。
Data Exception Message: An error occurred when trying to create a controller of type 'FranchiseUserController'. Make sure that the controller has a parameterless public constructor. Data Exception Type: System.InvalidOperationException
数据异常消息:试图创建类型为“加盟商用户控制器”的控制器时发生错误。确保控制器有一个无参数的公共构造函数。数据异常类型:System.InvalidOperationException
Here is the constructor from the controller that is mentioned in the error and the method that was being called.
这是错误中提到的控制器的构造函数和正在调用的方法。
The constructor
构造函数
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;
}
}
}
...and the method
…和方法
[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;
}
//});
}
1 个解决方案
#1
2
Most likely, you have code in your controller constructor that accesses the HttpControllerContext
in some way. You may be running into situations where the HttpControllerContext
is not ready before the controller is created (perhaps during an application pool restart).
最可能的情况是,您的控制器构造函数中有以某种方式访问HttpControllerContext的代码。您可能会遇到这样的情况:在创建控制器之前,HttpControllerContext还没有准备好(可能是在应用程序池重新启动期间)。
It is best to keep your controller constructors simple, since they may be created at any point during the lifecycle of the application. If you were using DI, I would suggest to move your complex logic into a service and don't do anything in the constructors except assign services. However, since you are not using DI, you could potentially fix this issue by moving your logic into the Initialize
event of your controller, and removing the constructor entirely.
最好让您的控制器构造函数保持简单,因为它们可以在应用程序生命周期的任何时刻创建。如果您正在使用DI,我建议将复杂的逻辑移动到服务中,除了分配服务之外,在构造函数中不要做任何事情。但是,由于您没有使用DI,所以您可以通过将逻辑转移到控制器的初始化事件中,并完全删除构造函数来解决这个问题。
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;
}
}
}
NOTE: I cannot say for certain this is what is happening in your application, however you should always assume there is no HTTP Context available at the time a controller is instantiated.
注意:我不能确定在您的应用程序中发生了什么,但是您应该始终假设在实例化控制器时没有可用的HTTP上下文。
On a side note, this logic looks like a cross-cutting concern. You should be doing it in a filter, not repeating it in every controller.
另一方面,这种逻辑看起来像是一个横切的关注点。你应该在过滤器中做,而不是在每个控制器中重复。
#1
2
Most likely, you have code in your controller constructor that accesses the HttpControllerContext
in some way. You may be running into situations where the HttpControllerContext
is not ready before the controller is created (perhaps during an application pool restart).
最可能的情况是,您的控制器构造函数中有以某种方式访问HttpControllerContext的代码。您可能会遇到这样的情况:在创建控制器之前,HttpControllerContext还没有准备好(可能是在应用程序池重新启动期间)。
It is best to keep your controller constructors simple, since they may be created at any point during the lifecycle of the application. If you were using DI, I would suggest to move your complex logic into a service and don't do anything in the constructors except assign services. However, since you are not using DI, you could potentially fix this issue by moving your logic into the Initialize
event of your controller, and removing the constructor entirely.
最好让您的控制器构造函数保持简单,因为它们可以在应用程序生命周期的任何时刻创建。如果您正在使用DI,我建议将复杂的逻辑移动到服务中,除了分配服务之外,在构造函数中不要做任何事情。但是,由于您没有使用DI,所以您可以通过将逻辑转移到控制器的初始化事件中,并完全删除构造函数来解决这个问题。
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;
}
}
}
NOTE: I cannot say for certain this is what is happening in your application, however you should always assume there is no HTTP Context available at the time a controller is instantiated.
注意:我不能确定在您的应用程序中发生了什么,但是您应该始终假设在实例化控制器时没有可用的HTTP上下文。
On a side note, this logic looks like a cross-cutting concern. You should be doing it in a filter, not repeating it in every controller.
另一方面,这种逻辑看起来像是一个横切的关注点。你应该在过滤器中做,而不是在每个控制器中重复。