【问题标题】:Razor Pages - Trying to Implement Action Filter on Razor PageRazor 页面 - 尝试在 Razor 页面上实现操作过滤器
【发布时间】:2019-05-01 12:07:57
【问题描述】:

我想编写一个自定义过滤器来检查用户是否登录到我的网站,如果没有,则将他们重定向回登录页面。

我希望过滤器在加载时自动应用于页面。

我已经尝试了下面的解决方案,但过滤器暂时不起作用。

过滤代码:

using Microsoft.AspNetCore.Mvc.Filters;

namespace MODS.Filters
{
    public class AuthorisationPageFilter : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            System.Diagnostics.Debug.Write("Filter Executed");  //write to debugger to test if working

            //add real code here

            base.OnActionExecuted(context);
        }
    }
}

接下来,这里是应用于页面模型的过滤器属性:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using MODS.Filters;

namespace MODS.Pages.Menus
{
    [AuthorisationPageFilter]
    public class Admin_MainMenuModel : PageModel
    {
        public ActionResult Admin_MainMenu()
        {
            System.Diagnostics.Debug.Write("Function Executed");
            return new ViewResult();
        }
    }
}

我的印象是您需要在页面上调用一个动作/方法才能在页面加载时应用该功能(请告诉我这是否正确),所以这里是调用Admin_MainMenu方法的代码在 .cshtml 页面文件中(在 razor 页面顶部的代码块中):

Model.Admin_MainMenu();

我目前的想法是: 1.过滤器本身的类型错误(可能是IPageFilter?) 2.我实现它的方式是错误的(无论我将它应用于 页面模型,或者当我在页面上调用方法时)。

非常感谢任何帮助。谢谢。

【问题讨论】:

  • 您是否使用 Identity 来管理身份验证?如果是这样,您可以将 [Authorize] 放在您的 PageModel 上。如果没有,您如何对用户进行身份验证?

标签: c# razor filter razor-pages action-filter


【解决方案1】:

ActionFilterAttribute 用于 MVC(控制器和操作)。对于 Razor 页面,您必须使用 IPageFilterIAsyncPageFilter 用于异步实现)。

There are two different filter pipelines for MVC and Razor Pages

Razor 页面过滤器 IPageFilterIAsyncPageFilter 允许 Razor 页面在运行 Razor 页面处理程序之前和之后运行代码。 Razor 页面筛选器类似于 ASP.NET Core MVC 操作筛选器,但它们不能应用于单个页面处理程序方法。

Filter methods for Razor Pages in ASP.NET Core

【讨论】:

    【解决方案2】:

    此答案适用于 AspNet MVC 而不是 AspNetCore MVC,但可能对某人有用:

    如果是为了授权,我会使用AuthorizeAttribute 类。

    类似这样的:

    using System.Web.Mvc;
    
    namespace MODS.Filters
    {
        public class CustomAuthorizeUserAttribute : AuthorizeAttribute
        {
            // Custom property, such as Admin|User|Anon
            public string AccessLevel { get; set; }
    
            // Check to see it the user is authorized
            protected override bool AuthorizeCore(HttpContextBase httpContext)
            {
                System.Diagnostics.Debug.Write("Authorize Executed");  //write to debugger to test if working
    
                // Use Core MVC Security Model
                var isAuthorized = base.AuthorizeCore(httpContext);
                if (!isAuthorized)
                {
                    return false;
                }
    
                // Or use your own method of checking that the user is logged in and authorized. Returns a Boolean value.
                return MySecurityHelper.CheckAccessLevel(AccessLevel);
            }
    
            // What to do when not authorized
            protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
            {
                filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary(
                            new
                            {
                                controller = "Error",
                                action = "NotFound"
                            })
                        );
            }
        }
    }
    

    然后用CustomAuthorizeUser属性装饰控制器或动作:

    using MODS.Filters;
    
    namespace MODS.Pages.Menus
    {
        [CustomAuthorizeUser(AccessLevel = "Admin")]
        public class Admin_MainMenuModel : PageModel
        {
            public ActionResult Admin_MainMenu()
            {
                System.Diagnostics.Debug.Write("Function Executed");
                return new ViewResult();
            }
        }
    }
    

    希望这会有所帮助!

    【讨论】:

    • 感谢您的回答。不幸的是,: AuthorizeAttribute 类似乎只在 ASP.NET MVC 中可用,而不是在我正在使用的 ASP.NET Core 中。我的主要问题是如何实现: ActionFilterAttribute(或更合适的 .NET 核心等效项),以便在每次页面加载完成时使用过滤器。
    • 好吧,我没有意识到这一点。我发现了这个问题,其中有一些很好的答案可能会有所帮助:stackoverflow.com/questions/31464359/…
    • 谢谢,我认为这篇文章会很有用。作为一个附带问题,我想知道过滤器是否真的是进行这种重定向的最佳方式。我是 ASP.NET 的新手,想知道您(或其他任何人)是否对此事有意见。
    【解决方案3】:

    就像ActionFilterAttribute 一样简单。您只需创建一个实现IPageFilterIAsyncPageFilterAttribute 派生类(两者都可以)。

    [AttributeUsage(AttributeTargets.Class)]
    public class CustomPageFilterAttribute : Attribute, IAsyncPageFilter
    {
        // Executes first
        public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
        {
            // TODO: implement this
        }
    
        // Executes last
        public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
        {
            // Before action execution
    
            await next();
    
            // After action execution
        }
    }
    

    现在,您可以在 PageModel 中使用您的属性。

    [CustomPageFilter]
    public class IndexModel : PageModel
    {
        public void OnGet() { }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-17
      • 2019-05-22
      • 2020-11-06
      • 2021-08-16
      • 1970-01-01
      • 2021-04-22
      • 2018-01-26
      • 2019-04-09
      • 2021-06-26
      相关资源
      最近更新 更多