首页 > 解决方案 > 根据 ASP.NET Core 站点中的 AuthorizeFilter 和 AllowAnonymous 属性动态确定布局

问题描述

我的 ASP.NET Core 3.1 站点有两种布局。一种用于经过身份验证的用户,称为“_Layout.Authenticated”,另一种用于未经身份验证的用户,称为“_Layout.Unauthenticated”。而不是使用 ViewStart.cshtml 将默认布局指定为最常用的布局,然后在视图本身上为其他视图指定布局,我希望站点动态确定这一点。

我确实有一个使用动作过滤器的解决方案,并想看看是否有更好的方法。

我创建了一个自定义操作过滤器,它将使用布局名称设置 ViewData 项,如下所示:

public class LayoutSelectionActionFilterAttribute : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        ActionExecutedContext resultContext = await next().ConfigureAwait(false);

        if (resultContext.Result is ViewResult viewResult)
        {
            viewResult.ViewData["LayoutName"] = HasAllowAnonymous(context)
                ? "_Layout.Unauthenticated"
                : "_Layout.Authenticated";
        }
    }

    private static bool HasAllowAnonymous(FilterContext context)
    {
        IList<IFilterMetadata> filters = context.Filters;

        if (filters.OfType<IAllowAnonymousFilter>().Any())
        {
            return true;
        }

        Endpoint endpoint = context.HttpContext.GetEndpoint();

        return endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null;
    }
}

我的 ViewStart.cshtml 看起来像这样:

@{
    Layout =  ViewData["LayoutName"] as string;
}

最后,我在 Startup.cs 中设置过滤器,如下所示:

services.AddControllersWithViews(options =>
{
     AuthorizationPolicy authorizationPolicyBuilder = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();

     options.Filters.Add(new AuthorizeFilter(authorizationPolicyBuilder));
     options.Filters.Add(new LayoutSelectionActionFilterAttribute());
 });

标签: c#asp.net-coreasp.net-core-mvc

解决方案


推荐阅读