我正在使用MVC5项目.在这个项目中,我总是希望在客户的每一个响应中做一些事情.
例如,我总是希望查看用户是否已登录,如果是,则将用户名和他们的id放入ViewBag变量中以便在.cshtml文件中使用.
我有一个所有其他控制器继承的基本控制器.我的第一个想法是在该控制器的构造函数中执行这些操作,但这不起作用,因为User变量尚不存在.
还有另一种方法可以做到这一点,而不是在每个Action中调用Setup()方法吗?
我可以在返回ActionResult之前监听一些事件并在那里插入我的ViewBag数据吗?
什么不起作用的例子;)
[InitializeSimpleMembership]
public class BaseController : Controller
{
protected USDatabase _database = new USDatabase();
public BaseController()
{
if (User.Identity.IsAuthenticated == true)
{
var usr = _database.UserProfiles.Where(x => x.UserName.ToLower() == User.Identity.Name.ToLower()).FirstOrDefault();
if (usr != null)
{
ViewBag.UserName = usr.UserName;
ViewBag.UserId = usr.Id;
}
}
}
}
阅读以下答案中的想法后我的解决方案:
创建了我在基本控制器上触发的Actionfilter.
public class UserDataFilter : ActionFilterAttribute
{
//OnActionExecuting – This method is called before a controller action is executed.
//OnActionExecuted – This method is called after a controller action is executed.
//OnResultExecuting – This method is called before a controller action result is executed.
//OnResultExecuted – This method is called after a controller action result is executed.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var User = filterContext.HttpContext.User;
if (User.Identity.IsAuthenticated == true)
{
using (var db = new USDatabase()) {
var usr = db.UserProfiles.Where(x => x.UserName.ToLower() == User.Identity.Name.ToLower()).FirstOrDefault();
if (usr != null)
{
var ViewBag = filterContext.Controller.ViewBag;
ViewBag.UserName = usr.UserName;
ViewBag.UserId = usr.Id;
}
}
}
}
}
基本控制器现在看起来像这样:
[InitializeSimpleMembership]
[UserDataFilter]
public class BaseController : Controller
{
protected USDatabase _database = new USDatabase();
public BaseController()
{
}
}
而我所有的其他控制器都实现了BaseController.
最佳答案 是..你需要的是一个动作过滤器,动作过滤器是.net属性从ActionFilterAttribute继承你可以做你用它们指定的东西,这里有一个理解它们的链接和一些关于你用它们做什么的基本样本: