home控制器中每个mvc actionresult的代码相同

本文关键字:代码 actionresult mvc 控制器 home | 更新日期: 2023-09-27 18:04:41

所以我有一些通用的操作结果,链接到各种视图。布局页面包含对adfs的调用,以填充每个页面必须使用的登录用户名。如下所示:

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

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

    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并调用那个partialview,但结果并不理想。我肯定我错过了一些简单的东西。

希望你们中的一些人能帮忙。谢谢。

home控制器中每个mvc actionresult的代码相同

我们使用一个抽象控制器并重写它的OnActionExecuting方法来在实际的action方法被调用之前执行代码。有了这个抽象控制器,你所要做的就是让其他控制器继承它来获得它的功能。我们还使用这个基本控制器作为一个地方来定义其他扩展它的控制器可以使用的其他助手方法,如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类中实现,它允许你装饰你的控制器,而不是使用继承,但最终结果是相同的。下面是一个自定义控制器属性实现的例子:

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

使用OnActionExecuting的另一种替代方法,因为这只是模板的一部分,将给它自己的动作方法,返回部分并调用@Html.Action()