我问了一个相关的问题但是搞砸了标题,没有人会理解它.由于我现在能够更准确地提出这个问题,我决定在一个新问题中重新制定它并关闭旧问题.对不起.
所以我想要做的是将数据(我的自定义用户的昵称存储在数据库中)传递给LoginUserControl.此登录通过Html.RenderPartial()从主页面呈现,因此我真正需要做的是确保每次调用时都出现ViewData ["UserNickname"].但我不想在每个控制器的每个动作中填充ViewData ["UserNickname"],所以我决定使用这种方法并创建一个抽象的基本控制器,它将为我完成工作,如下所示:
public abstract class ApplicationController : Controller { private IUserRepository _repUser; public ApplicationController() { _repUser = RepositoryFactory.getUserRepository(); var loggedInUser = _repUser.FindById(User.Identity.Name); //Problem! ViewData["LoggedInUser"] = loggedInUser; } }
这样,无论我的推导控制器做什么,用户信息都已经存在.
到现在为止还挺好.现在出现问题:
我无法调用User.Identity.Name,因为User
它已经为空.在我的所有派生控制器中都不是这种情况,因此这是抽象基本控制器特有的.
我在代码中的另一个地方通过FormsAuthentication设置User.Identity.Name,但我认为这不是问题 - afaik User.Identity.Name可以为null,但不是User本身.
在我看来HttpContext不可用(因为也是null ;-)而且我在这里错过了一个简单而重要的观点.任何人都可以给我一些提示吗?我真的很感激.
这个问题的答案实际上非常简单.由于Raimond指出的原因,我无法在构造函数中执行代码,但我可以在构造函数之外执行.
所以我所做的是覆盖基本控制器类中的onActionExecuting()(我为它创建了一个自定义属性,但只是覆盖该方法也应该工作),然后从那里进行我的用户查找.
现在它按预期工作,我没有重复的代码.
在实例化Controller之后才会分配User属性,但您可以通过以下方式从构造函数获得早期访问权限:
System.Web.HttpContext.Current.User
我的猜测是Controller的基本构造函数没有填写用户,但只有在为Controller设置ControllerContext时才知道它.你应该在关于MVC应用程序生命周期的文档中检查这个(这里可能会做的,虽然它可能有点过时,因为它是预览版本),或者只是检查MVC的源代码.
从我有MVC的代码(也是一个预览版本,但应该没问题):(在控制器中)
public IPrincipal User { get { return HttpContext == null ? null : HttpContext.User; } }
...
public HttpContextBase HttpContext { get { return ControllerContext == null ? null : ControllerContext.HttpContext; } }
我没有看到代码中的默认构造函数的实现.这将证明ControllerContext在构造时为空.
所以你应该在其他地方执行你的代码.