如何在每个页面上调用相同的操作?

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 中即可。会话变量可以是通用的。