Razor 页面 - 尝试在 Razor 页面上实现操作过滤器

bbb*_*bbb 5 c# filter action-filter razor razor-pages

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

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

我已经尝试了下面所示的解决方案,但过滤器目前不起作用。

过滤器代码:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Model.Admin_MainMenu();
Run Code Online (Sandbox Code Playgroud)

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

任何帮助是极大的赞赏。谢谢。

小智 7

ActionFilterAttribute适用于 MVC(控制器和操作)。对于 Razor Pages,您必须使用IPageFilter(IAsyncPageFilter用于异步实现)。

MVC 和 Razor Pages 有两种不同的过滤器管道

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

ASP.NET Core 中 Razor 页面的筛选方法


Sal*_*vaf 5

就像 一样简单ActionFilterAttribute。您所需要的只是创建一个实现或 的Attribute派生类(两者都可以)。IPageFilterIAsyncPageFilter

[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
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在PageModel.

[CustomPageFilter]
public class IndexModel : PageModel
{
    public void OnGet() { }
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*t D 0

这个答案适用于 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"
                        })
                    );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后用属性装饰控制器或操作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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!