3

所以我有一些通用的 actionresults 暂时链接到各种视图。布局页面包含对 adfs 的调用,以填充必须用于每个页面的登录用户名。看起来像这样:

            <div class="float-right">
                <section id="login">
                   Hello, <span class="username">@ViewBag.GivenName @ViewBag.LastName</span>!
                </section>
            </div>

在家庭控制器中,使这个登录名起作用的是这里的代码:

    public ActionResult Index()
    {
        ClaimsIdentity claimsIdentity = Thread.CurrentPrincipal.Identity as ClaimsIdentity;
        Claim claimGivenName = claimsIdentity.FindFirst("http://sts.msft.net/user/FirstName");
        Claim claimLastName = claimsIdentity.FindFirst("http://sts.msft.net/user/LastName");

        if (claimGivenName == null || claimLastName == null)
        {
            ViewBag.GivenName = "#FAIL";
        }
        else
        {
            ViewBag.GivenName = claimGivenName.Value;
            ViewBag.LastName = claimLastName.Value;
        }


        return View();
    }

但如前所述,我需要在用户访问每个链接(actionresult)时显示它。因此,为了实现这一点,我必须将上面的所有代码发布到每个 actionresult 中。

有什么方法可以将其应用于整个操作结果,而不必将代码从一个操作复制到另一个操作?我确实尝试为我的 _Layout.cshtml 注册到 actionresult 并调用该部分视图,但这并没有给我带来有利的结果。我敢肯定,我缺少一些简单的东西。

希望你们中的一些人能提供帮助。非常感谢。

4

3 回答 3

1

我们使用抽象控制器并覆盖其OnActionExecuting方法以在调用实际操作方法之前执行代码。使用这个抽象控制器,您所要做的就是让任何其他控制器从它继承来获得它的功能。我们还使用这个基本控制器作为定义其他扩展它的控制器可以使用的其他辅助方法的地方,例如GetUsernameForAuthenticatedUser().

public abstract class AbstractAuthenticationController : Controller
{
    private readonly IAuthenticationService _authService;

    protected AbstractAuthenticationController()
    {
        _authService = AuthenticationServiceFactory.Create();
    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        EnsureUserIsAuthenticated();
    }

    internal void EnsureUserIsAuthenticated()
    {
        if (!_authService.IsUserAuthenticated())
        {
            _authService.Login();
        }
    }

    protected string GetUsernameForAuthenticatedUser()
    {
        var identityName = System.Web.HttpContext.Current.User.Identity.Name;
        var username = _authService.GetUsername(identityName);
        if (username == null) throw new UsernameNotFoundException("No Username for " + identityName);
        return username;
    }
}

此功能也可以在Attribute允许您装饰控制器而不是使用继承的类中实现,但最终结果是相同的。这是一个自定义控制器属性实现的示例

于 2013-03-19T22:32:33.020 回答
0

使用 as this 的另一种方法OnActionExecuting仅适用于模板的一部分,即为其提供自己的操作方法,该方法返回一个部分并调用@Html.Action()

于 2013-03-20T10:24:46.443 回答
0

您可以创建一个基本控制器并使所有控制器都继承自它。将设置给定和姓氏的代码移动到单独的受保护方法中,并在需要时调用它。Initialize我认为您可以在基本控制器的方法中调用该函数。这样您就不需要将其直接调用到操作中。您还可以创建模型层次结构并在基础模型上具有GivenName和作为属性,而不是使用.LastNameViewBag

于 2013-03-19T22:14:45.553 回答