首页 文章

我'm not using dependency injection, but I'得到“尝试创建类型的控制器时发生错误”

提问于
浏览
2

我已经看到很多关于不正确使用依赖注入会导致错误的答案......

尝试创建“FranchiseUserController”类型的控制器时发生错误 . 确保控制器具有无参数的公共构造函数 .

但我没有使用任何依赖注入产品,如Ninject,Unity等 . 此外,这个错误不会发生在我的本地开发环境中,但是当我们在我们的QA服务器上进行测试时会出现 . 此外,它间歇性地发生,并且它发生在我的几个Web API方法中 . 它出现在多个用户和多个浏览器中 .

我不确定在这里发布什么代码 . 如果您需要更多信息,请告诉我,我很乐意发布 .

这是使用AngularJS的ASP.NET MVC / WebAPI应用程序 . 从Angular客户端调用Web API控制器时发生错误 . 角度应用程序在错误回调中接收响应,其中包含500内部服务器错误...

数据异常消息:尝试创建“FranchiseUserController”类型的控制器时发生错误 . 确保控制器具有无参数的公共构造函数 . 数据异常类型: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;
    }
    //});
}

1 回答

  • 2

    最有可能的是,您的控制器构造函数中的代码以某种方式访问 HttpControllerContext . 在创建控制器之前(可能在应用程序池重新启动期间),您可能会遇到 HttpControllerContext 未就绪的情况 .

    最好是keep your controller constructors simple,因为它们可以在应用程序的生命周期中的任何时刻创建 . 如果您使用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上下文 .

    另一方面,这种逻辑看起来像是一个贯穿各领域的问题 . 您应该在filter中执行此操作,而不是在每个控制器中重复它 .

相关问题