如何在每个页面上调用相同的操作?
How can I call the same Action on every page?
我想在 _Layout
视图中调用以下 ActionResult
。这些属性将用于控制导航栏上显示的内容:
[ChildActionOnly]
public ActionResult GenerateLayout()
{
var loseATonEvent = db.Events.Max(e => e.EventId);
var currentUser = User.Identity.Name;
currentUser = currentUser.Contains('\')
? currentUser.Substring(currentUser.LastIndexOf('\') + 1)
: currentUser;
var layout = new NavigationViewModel
{
IsAdmin = User.IsInRole("ITS-Dept"),
IsSignedUp = ConfirmIsSignedUp(loseATonEvent, currentUser),
CanSignUp = ConfirmCanSignUp(loseATonEvent),
CanWeighIn = ConfirmCanWeighIn(loseATonEvent)
};
return PartialView("_Layout", layout);
}
据我所知,为了做到这一点,我需要使用 @Html.RenderAction()
。在我的 _Layout
视图中,我有以下内容:
@{
Html.RenderAction("GenerateLayout", "Navigation");
}
但是,这只会创建一个无限循环。我的问题是,我怎样才能避免这种情况?有没有简单的方法 return 这个视图模型?或者有没有更好的方法来解决这个问题,这样我就不需要在每次加载页面后都调用它?
如果您的导航是自包含的,那么不要 returning _Layout
,而是将您的导航分成另一个部分,然后 return 那样。
您的控制器方法将构建视图模型和return 导航
return PartialView("_Navigation", layout);
_Navigation 将包含您的导航标记,并将使用您的视图模型确定需要显示的内容和需要隐藏的内容。
_Layout,无需检索属性并确定需要显示的内容,只需按原样呈现操作。
另一种方法是利用 'Session' 数据来包含您的值,然后将您的 _Layout 菜单条件基于该数据。
例如,当有人登录...
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
// validate user here
if (validUser)
{
var loseATonEvent = db.Events.Max(e => e.EventId);
var currentUser = User.Identity.Name;
Session["isSignedUp"] = ConfirmIsSignedUp(loseATonEvent, currentUser);
Session["canSignUp"] = ConfirmCanSignUp(loseATonEvent);
Session["canWeighIn"] = ConfirmCanWeighIn(loseATonEvent);
// return user to destination URL
return Redirect(returnUrl);
}
}
所以现在我们有 Session 变量可以在条件中使用来构建我们的导航。
@if (User.Identity.IsAuthenticated && User.IsInRole("ITS-Dept"))
{
// add the nav element here for "ITS-Dept" users
}
@if (User.Identity.IsAuthenticated && Session["isSignedUp"] == "true")
{
// add nav element for this Session val
}
@if (User.Identity.IsAuthenticated && Session["canSignUp"] == "true")
{
// add nav element for this Session val
}
@if (User.Identity.IsAuthenticated && Session["canWeighIn"] == "true")
{
// add nav element for this Session val
}
您只需将它们直接添加到您的 _Layout 中即可。会话变量可以是通用的。
我想在 _Layout
视图中调用以下 ActionResult
。这些属性将用于控制导航栏上显示的内容:
[ChildActionOnly]
public ActionResult GenerateLayout()
{
var loseATonEvent = db.Events.Max(e => e.EventId);
var currentUser = User.Identity.Name;
currentUser = currentUser.Contains('\')
? currentUser.Substring(currentUser.LastIndexOf('\') + 1)
: currentUser;
var layout = new NavigationViewModel
{
IsAdmin = User.IsInRole("ITS-Dept"),
IsSignedUp = ConfirmIsSignedUp(loseATonEvent, currentUser),
CanSignUp = ConfirmCanSignUp(loseATonEvent),
CanWeighIn = ConfirmCanWeighIn(loseATonEvent)
};
return PartialView("_Layout", layout);
}
据我所知,为了做到这一点,我需要使用 @Html.RenderAction()
。在我的 _Layout
视图中,我有以下内容:
@{
Html.RenderAction("GenerateLayout", "Navigation");
}
但是,这只会创建一个无限循环。我的问题是,我怎样才能避免这种情况?有没有简单的方法 return 这个视图模型?或者有没有更好的方法来解决这个问题,这样我就不需要在每次加载页面后都调用它?
如果您的导航是自包含的,那么不要 returning _Layout
,而是将您的导航分成另一个部分,然后 return 那样。
您的控制器方法将构建视图模型和return 导航
return PartialView("_Navigation", layout);
_Navigation 将包含您的导航标记,并将使用您的视图模型确定需要显示的内容和需要隐藏的内容。
_Layout,无需检索属性并确定需要显示的内容,只需按原样呈现操作。
另一种方法是利用 'Session' 数据来包含您的值,然后将您的 _Layout 菜单条件基于该数据。
例如,当有人登录...
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
// validate user here
if (validUser)
{
var loseATonEvent = db.Events.Max(e => e.EventId);
var currentUser = User.Identity.Name;
Session["isSignedUp"] = ConfirmIsSignedUp(loseATonEvent, currentUser);
Session["canSignUp"] = ConfirmCanSignUp(loseATonEvent);
Session["canWeighIn"] = ConfirmCanWeighIn(loseATonEvent);
// return user to destination URL
return Redirect(returnUrl);
}
}
所以现在我们有 Session 变量可以在条件中使用来构建我们的导航。
@if (User.Identity.IsAuthenticated && User.IsInRole("ITS-Dept"))
{
// add the nav element here for "ITS-Dept" users
}
@if (User.Identity.IsAuthenticated && Session["isSignedUp"] == "true")
{
// add nav element for this Session val
}
@if (User.Identity.IsAuthenticated && Session["canSignUp"] == "true")
{
// add nav element for this Session val
}
@if (User.Identity.IsAuthenticated && Session["canWeighIn"] == "true")
{
// add nav element for this Session val
}
您只需将它们直接添加到您的 _Layout 中即可。会话变量可以是通用的。