ASP.NET Core'da Sayfalar için Razor filtreleme yöntemleri

Gönderen Rick Anderson

RazorSayfa, IPageFilterIAsyncPageFilter sayfa Razor işleyicisi çalıştırıldıktan önce ve çalıştırıldıktan sonra Sayfaların kod çalıştırmasına izin verirRazor. RazorSayfa filtreleri ASP.NET Temel MVC eylem filtrelerine benzer, ancak tek tek sayfa işleyici yöntemlerine uygulanamaz.

Razor Sayfa filtreleri:

  • İşleyici yöntemi seçildikten sonra ancak model bağlaması gerçekleşmeden önce kodu çalıştırın.
  • İşleyici yöntemi yürütülmeden önce, model bağlama tamamlandıktan sonra kodu çalıştırın.
  • İşleyici yöntemi yürütülürken kodu çalıştırın.
  • Bir sayfada veya genel olarak uygulanabilir.
  • Belirli sayfa işleyici yöntemlerine uygulanamaz.
  • Bağımlılık Ekleme (DI) ile doldurulan oluşturucu bağımlılıkları olabilir. Daha fazla bilgi için bkz . ServiceFilterAttribute ve TypeFilterAttribute.

Sayfa oluşturucuları ve ara yazılım, bir işleyici yöntemi yürütülmeden önce özel kodun yürütülmesini etkinleştirse de, yalnızca Razor Sayfa filtreleri ve sayfaya HttpContext erişimi etkinleştirir. Ara yazılımların HttpContextöğesine erişimi vardır, ancak "sayfa bağlamı" erişimine sahip değildir. Filtreler, öğesine erişim sağlayan türetilmiş bir FilterContext parametreye HttpContextsahiptir. Sayfa filtresi örneği: Yanıta üst bilgi ekleyen bir filtre özniteliği uygulayın; oluşturucular veya ara yazılım ile yapılamaz. Sayfanın örneklerine ve modeline erişimi içeren sayfa bağlamı erişimi yalnızca filtreler, işleyiciler veya sayfanın Razor gövdesi yürütülürken kullanılabilir.

Örnek kodu görüntüleme veya indirme (indirme)

Razor Sayfa filtreleri, genel olarak veya sayfa düzeyinde uygulanabilen aşağıdaki yöntemleri sağlar:

  • Zaman uyumlu yöntemler:

    • OnPageHandlerSelected : İşleyici yöntemi seçildikten sonra ancak model bağlaması gerçekleşmeden önce çağrılır.
    • OnPageHandlerExecuting : İşleyici yöntemi yürütülmeden önce, model bağlama tamamlandıktan sonra çağrılır.
    • OnPageHandlerExecuted : İşleyici yöntemi yürütülürken, eylem sonucundan önce çağrılır.
  • Zaman uyumsuz yöntemler:

    • OnPageHandlerSelectionAsync : İşleyici yöntemi seçildikten sonra ancak model bağlaması gerçekleşmeden önce zaman uyumsuz olarak çağrılır.
    • OnPageHandlerExecutionAsync : model bağlama tamamlandıktan sonra işleyici yöntemi çağrılmadan önce zaman uyumsuz olarak çağrılır.

Her ikisini birden değil, bir filtre arabiriminin zaman uyumlu veya zaman uyumsuz sürümünü uygulayın. Çerçeve önce filtrenin zaman uyumsuz arabirimi uygulayıp uygulamadığını denetler ve uygulanıyorsa bunu çağırır. Aksi takdirde zaman uyumlu arabirimin yöntemlerini çağırır. Her iki arabirim de uygulanırsa, yalnızca zaman uyumsuz yöntemler çağrılır. Aynı kural sayfalardaki geçersiz kılmalar için de geçerlidir, her ikisini de değil, zaman uyumlu veya zaman uyumsuz geçersiz kılma sürümünü uygular.

Sayfa filtrelerini genel olarak uygulama Razor

Aşağıdaki kod şunu uygular IAsyncPageFilter:

public class SampleAsyncPageFilter : IAsyncPageFilter
{
    private readonly IConfiguration _config;

    public SampleAsyncPageFilter(IConfiguration config)
    {
        _config = config;
    }

    public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
    {
        var key = _config["UserAgentID"];
        context.HttpContext.Request.Headers.TryGetValue("user-agent",
                                                        out StringValues value);
        ProcessUserAgent.Write(context.ActionDescriptor.DisplayName,
                               "SampleAsyncPageFilter.OnPageHandlerSelectionAsync",
                               value, key.ToString());

        return Task.CompletedTask;
    }

    public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context,
                                                  PageHandlerExecutionDelegate next)
    {
        // Do post work.
        await next.Invoke();
    }
}

Yukarıdaki kodda, ProcessUserAgent.Write kullanıcı aracısı dizesiyle çalışan kullanıcı tarafından sağlanan koddur.

Aşağıdaki kod sınıfında öğesini SampleAsyncPageFilterStartup etkinleştirir:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.Filters.Add(new SampleAsyncPageFilter(Configuration));
        });
}

Aşağıdaki kod, /Movies içindeki yalnızca sayfalara uygulamak için çağrı yaparAddFolderApplicationModelConvention:SampleAsyncPageFilter

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages(options =>
    {
        options.Conventions.AddFolderApplicationModelConvention(
            "/Movies",
            model => model.Filters.Add(new SampleAsyncPageFilter(Configuration)));
    });
}

Aşağıdaki kod zaman uyumlu IPageFilteruygular:

public class SamplePageFilter : IPageFilter
{
    private readonly IConfiguration _config;

    public SamplePageFilter(IConfiguration config)
    {
        _config = config;
    }

    public void OnPageHandlerSelected(PageHandlerSelectedContext context)
    {
        var key = _config["UserAgentID"];
        context.HttpContext.Request.Headers.TryGetValue("user-agent", out StringValues value);
        ProcessUserAgent.Write(context.ActionDescriptor.DisplayName,
                               "SamplePageFilter.OnPageHandlerSelected",
                               value, key.ToString());
    }

    public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
    {
        Debug.WriteLine("Global sync OnPageHandlerExecuting called.");
    }

    public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
    {
        Debug.WriteLine("Global sync OnPageHandlerExecuted called.");
    }
}

Aşağıdaki kod şunları etkinleştirir SamplePageFilter:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.Filters.Add(new SamplePageFilter(Configuration));
        });
}

Filtre yöntemlerini geçersiz kılarak Sayfa filtrelerini uygulama Razor

Aşağıdaki kod zaman uyumsuz Razor Sayfa filtrelerini geçersiz kılar:

public class IndexModel : PageModel
{
    private readonly IConfiguration _config;

    public IndexModel(IConfiguration config)
    {
        _config = config;
    }

    public override Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
    {
        Debug.WriteLine("/IndexModel OnPageHandlerSelectionAsync");
        return Task.CompletedTask;
    }

    public async override Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, 
                                                           PageHandlerExecutionDelegate next)
    {
        var key = _config["UserAgentID"];
        context.HttpContext.Request.Headers.TryGetValue("user-agent", out StringValues value);
        ProcessUserAgent.Write(context.ActionDescriptor.DisplayName,
                               "/IndexModel-OnPageHandlerExecutionAsync",
                                value, key.ToString());

        await next.Invoke();
    }
}

Filtre özniteliği uygulama

Yerleşik öznitelik tabanlı filtre OnResultExecutionAsync filtresi alt sınıflandırılabilir. Aşağıdaki filtre yanıta bir üst bilgi ekler:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;

namespace PageFilter.Filters
{
    public class AddHeaderAttribute  : ResultFilterAttribute
    {
        private readonly string _name;
        private readonly string _value;

        public AddHeaderAttribute (string name, string value)
        {
            _name = name;
            _value = value;
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Response.Headers.Add(_name, new string[] { _value });
        }
    }
}

Aşağıdaki kod özniteliğini AddHeader uygular:

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

namespace PageFilter.Movies
{
    [AddHeader("Author", "Rick")]
    public class TestModel : PageModel
    {
        public void OnGet()
        {

        }
    }
}

Üst bilgileri incelemek için tarayıcı geliştirici araçları gibi bir araç kullanın. Yanıt Üst Bilgileri altında author: Rick görüntülenir.

Siparişi geçersiz kılma yönergeleri için bkz . Varsayılan siparişi geçersiz kılma.

Filtre işlem hattını filtreden kısa devre yapmaya yönelik yönergeler için bkz . İptal ve kısa devre .

Filtre özniteliğini yetkilendirme

Authorize özniteliği bir PageModel:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace PageFilter.Pages
{
    [Authorize]
    public class ModelWithAuthFilterModel : PageModel
    {
        public IActionResult OnGet() => Page();
    }
}

Gönderen Rick Anderson

RazorSayfa, IPageFilterIAsyncPageFilter sayfa Razor işleyicisi çalıştırıldıktan önce ve çalıştırıldıktan sonra Sayfaların kod çalıştırmasına izin verirRazor. RazorSayfa filtreleri ASP.NET Temel MVC eylem filtrelerine benzer, ancak tek tek sayfa işleyici yöntemlerine uygulanamaz.

Razor Sayfa filtreleri:

  • İşleyici yöntemi seçildikten sonra ancak model bağlaması gerçekleşmeden önce kodu çalıştırın.
  • İşleyici yöntemi yürütülmeden önce, model bağlama tamamlandıktan sonra kodu çalıştırın.
  • İşleyici yöntemi yürütülürken kodu çalıştırın.
  • Bir sayfada veya genel olarak uygulanabilir.
  • Belirli sayfa işleyici yöntemlerine uygulanamaz.

Kod, bir işleyici yöntemi sayfa oluşturucusu veya ara yazılım kullanılarak yürütülmeden önce çalıştırılabilir, ancak yalnızca Razor Sayfa filtrelerinin erişimi HttpContextvardır. Filtreler, öğesine erişim sağlayan türetilmiş bir FilterContext parametreye HttpContextsahiptir. Örneğin, Filtre özniteliği uygulama örneği, yanıta oluşturucular veya ara yazılım ile yapılamayan bir üst bilgi ekler.

Örnek kodu görüntüleme veya indirme (indirme)

Razor Sayfa filtreleri, genel olarak veya sayfa düzeyinde uygulanabilen aşağıdaki yöntemleri sağlar:

  • Zaman uyumlu yöntemler:

    • OnPageHandlerSelected : İşleyici yöntemi seçildikten sonra ancak model bağlaması gerçekleşmeden önce çağrılır.
    • OnPageHandlerExecuting : İşleyici yöntemi yürütülmeden önce, model bağlama tamamlandıktan sonra çağrılır.
    • OnPageHandlerExecuted : İşleyici yöntemi yürütülürken, eylem sonucundan önce çağrılır.
  • Zaman uyumsuz yöntemler:

    • OnPageHandlerSelectionAsync : İşleyici yöntemi seçildikten sonra ancak model bağlaması gerçekleşmeden önce zaman uyumsuz olarak çağrılır.
    • OnPageHandlerExecutionAsync : model bağlama tamamlandıktan sonra işleyici yöntemi çağrılmadan önce zaman uyumsuz olarak çağrılır.

Dekont

Her ikisini birden değil, bir filtre arabiriminin zaman uyumlu veya zaman uyumsuz sürümünü uygulayın. Çerçeve önce filtrenin zaman uyumsuz arabirimi uygulayıp uygulamadığını denetler ve uygulanıyorsa bunu çağırır. Aksi takdirde zaman uyumlu arabirimin yöntemlerini çağırır. Her iki arabirim de uygulanırsa, yalnızca zaman uyumsuz yöntemler çağrılır. Aynı kural sayfalardaki geçersiz kılmalar için de geçerlidir, her ikisini de değil, zaman uyumlu veya zaman uyumsuz geçersiz kılma sürümünü uygular.

Sayfa filtrelerini genel olarak uygulama Razor

Aşağıdaki kod şunu uygular IAsyncPageFilter:

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace PageFilter.Filters
{
    public class SampleAsyncPageFilter : IAsyncPageFilter
    {
        private readonly ILogger _logger;

        public SampleAsyncPageFilter(ILogger logger)
        {
            _logger = logger;
        }

        public async Task OnPageHandlerSelectionAsync(
                                            PageHandlerSelectedContext context)
        {
            _logger.LogDebug("Global OnPageHandlerSelectionAsync called.");
            await Task.CompletedTask;
        }

        public async Task OnPageHandlerExecutionAsync(
                                            PageHandlerExecutingContext context,
                                            PageHandlerExecutionDelegate next)
        {
            _logger.LogDebug("Global OnPageHandlerExecutionAsync called.");
            await next.Invoke();
        }
    }
}

Yukarıdaki kodda ILogger gerekli değildir. Uygulama için izleme bilgileri sağlamak için örnekte kullanılır.

Aşağıdaki kod sınıfında öğesini SampleAsyncPageFilterStartup etkinleştirir:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(new SampleAsyncPageFilter(_logger));
    });
}

Aşağıdaki kod, sınıfın tamamını Startup gösterir:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PageFilter.Filters;

namespace PageFilter
{
    public class Startup
    {
        ILogger _logger;
        public Startup(ILoggerFactory loggerFactory, IConfiguration configuration)
        {
            _logger = loggerFactory.CreateLogger<GlobalFiltersLogger>();
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options =>
            {
                options.Filters.Add(new SampleAsyncPageFilter(_logger));
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc();
        }
    }
}

Aşağıdaki kod yalnızca /subFolder içindeki sayfalara uygulamak SampleAsyncPageFilter için çağırırAddFolderApplicationModelConvention:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
       .AddRazorPagesOptions(options =>
       {
           options.Conventions.AddFolderApplicationModelConvention(
               "/subFolder",
               model => model.Filters.Add(new SampleAsyncPageFilter(_logger)));
       });
}

Aşağıdaki kod zaman uyumlu IPageFilteruygular:

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;

namespace PageFilter.Filters
{
    public class SamplePageFilter : IPageFilter
    {
        private readonly ILogger _logger;

        public SamplePageFilter(ILogger logger)
        {
            _logger = logger;
        }

        public void OnPageHandlerSelected(PageHandlerSelectedContext context)
        {
            _logger.LogDebug("Global sync OnPageHandlerSelected called.");
        }

        public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
        {
            _logger.LogDebug("Global sync PageHandlerExecutingContext called.");
        }

        public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
        {
            _logger.LogDebug("Global sync OnPageHandlerExecuted called.");
        }
    }
}

Aşağıdaki kod şunları etkinleştirir SamplePageFilter:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(new SamplePageFilter(_logger));
    });
}

Filtre yöntemlerini geçersiz kılarak Sayfa filtrelerini uygulama Razor

Aşağıdaki kod zaman uyumlu Razor Sayfa filtrelerini geçersiz kılar:

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace PageFilter.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ILogger _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }
        public string Message { get; set; }

        public void OnGet()
        {
            _logger.LogDebug("IndexModel/OnGet");
        }
        
        public override void OnPageHandlerSelected(
                                    PageHandlerSelectedContext context)
        {
            _logger.LogDebug("IndexModel/OnPageHandlerSelected");          
        }

        public override void OnPageHandlerExecuting(
                                    PageHandlerExecutingContext context)
        {
            Message = "Message set in handler executing";
            _logger.LogDebug("IndexModel/OnPageHandlerExecuting");
        }


        public override void OnPageHandlerExecuted(
                                    PageHandlerExecutedContext context)
        {
            _logger.LogDebug("IndexModel/OnPageHandlerExecuted");
        }
    }
}

Filtre özniteliği uygulama

Yerleşik öznitelik tabanlı filtre OnResultExecutionAsync filtresi alt sınıflandırılabilir. Aşağıdaki filtre yanıta bir üst bilgi ekler:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;

namespace PageFilter.Filters
{
    public class AddHeaderAttribute  : ResultFilterAttribute
    {
        private readonly string _name;
        private readonly string _value;

        public AddHeaderAttribute (string name, string value)
        {
            _name = name;
            _value = value;
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Response.Headers.Add(_name, new string[] { _value });
        }
    }
}

Aşağıdaki kod özniteliğini AddHeader uygular:

[AddHeader("Author", "Rick")]
public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILogger<ContactModel> logger)
    {
        _logger = logger;
    }
    public string Message { get; set; }

    public async Task OnGetAsync()
    {
        Message = "Your contact page.";
        _logger.LogDebug("Contact/OnGet");
        await Task.CompletedTask;
    }
}

Siparişi geçersiz kılma yönergeleri için bkz . Varsayılan siparişi geçersiz kılma.

Filtre işlem hattını filtreden kısa devre yapmaya yönelik yönergeler için bkz . İptal ve kısa devre .

Filtre özniteliğini yetkilendirme

Authorize özniteliği bir PageModel:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace PageFilter.Pages
{
    [Authorize]
    public class ModelWithAuthFilterModel : PageModel
    {
        public IActionResult OnGet() => Page();
    }
}