ASP.NET Core'daki filtreler

Kirk Larkin, Rick Anderson, Tom Dykstra ve Steve Smith tarafından

ASP.NET Core'daki filtreler , kodun istek işleme işlem hattındaki belirli aşamaların öncesinde veya sonrasında çalıştırılmasına olanak sağlar.

Yerleşik filtreler şunlar gibi görevleri işler:

  • Yetkilendirme, kullanıcının yetkilendirilmemiş kaynaklara erişimini engelleme.
  • Yanıt önbelleğe alma, önbelleğe alınmış bir yanıt döndürmek için istek işlem hattını kısa devreden geçirme.

Çapraz kesme sorunlarını çözmek için özel filtreler oluşturulabilir. Çapraz kesme endişelerine örnek olarak hata işleme, önbelleğe alma, yapılandırma, yetkilendirme ve günlüğe kaydetme verilebilir. Filtreler kodun çoğaltılmasını önler. Örneğin, hata işleme özel durum filtresi hata işlemeyi bir araya gelebilir.

Bu belge Sayfalar, API denetleyicileri ve görünümlere sahip denetleyiciler için Razor geçerlidir. Filtreler bileşenlerle Razordoğrudan çalışmaz. Filtre yalnızca şu durumlarda bir bileşeni dolaylı olarak etkileyebilir:

  • Bileşen bir sayfaya veya görünüme eklenir.
  • Sayfa veya denetleyici ve görünüm filtreyi kullanır.

Filtreler nasıl çalışır?

Filtreler, bazen filtre işlem hattı olarak da adlandırılan ASP.NET Core eylem çağırma işlem hattı içinde çalışır. Filtre işlem hattı, ASP.NET Core yürütülecek eylemi seçtikten sonra çalışır:

The request is processed through Other Middleware, Routing Middleware, Action Selection, and the Action Invocation Pipeline. The request processing continues back through Action Selection, Routing Middleware, and various Other Middleware before becoming a response sent to the client.

Filtre türleri

Her filtre türü, filtre işlem hattında farklı bir aşamada yürütülür:

  • Yetkilendirme filtreleri:

    • önce çalıştırın.
    • Kullanıcının istek için yetkilendirilip yetkilendirilmediğini belirleyin.
    • İstek yetkilendirilmediyse işlem hattını kısa devreye geçirin.
  • Kaynak filtreleri:

    • Yetkilendirmeden sonra çalıştırın.
    • OnResourceExecuting filtre işlem hattının geri kalanından önce kodu çalıştırır. Örneğin, OnResourceExecuting model bağlamadan önce kodu çalıştırır.
    • OnResourceExecuted işlem hattının geri kalanı tamamlandıktan sonra kodu çalıştırır.
  • Eylem filtreleri:

    • Bir eylem yöntemi çağrılmadan hemen önce ve sonra çalıştırın.
    • Bir eyleme geçirilen bağımsız değişkenleri değiştirebilir.
    • Eylemden döndürülen sonucu değiştirebilir.
    • Sayfalar'da Razor desteklenmez.
  • Uç nokta filtreleri:

    • Bir eylem yöntemi çağrılmadan hemen önce ve sonra çalıştırın.
    • Bir eyleme geçirilen bağımsız değişkenleri değiştirebilir.
    • Eylemden döndürülen sonucu değiştirebilir.
    • Sayfalar'da Razor desteklenmez.
    • Hem eylemlerde hem de yol işleyici tabanlı uç noktalarda çağrılabilir.
  • Özel durum filtreleri , yanıt gövdesi yazılmadan önce gerçekleşen işlenmeyen özel durumlara genel ilkeler uygular.

  • Sonuç filtreleri:

    • Eylem sonuçlarının yürütülmesinden hemen önce ve sonra çalıştırın.
    • Yalnızca eylem yöntemi başarıyla yürütürken çalıştırın.
    • Görünüm veya biçimlendirici yürütmeyi çevrelemesi gereken mantık için kullanışlıdır.

Aşağıdaki diyagramda filtre türlerinin filtre işlem hattında nasıl etkileşimde olduğu gösterilmektedir:

The request is processed through Authorization Filters, Resource Filters, Model Binding, Action Filters, Action Execution and Action Result Conversion, Exception Filters, Result Filters, and Result Execution. On the way out, the request is only processed by Result Filters and Resource Filters before becoming a response sent to the client.

RazorSayfalar, Sayfa işleyiciden önce ve sonra çalışan Sayfa filtrelerini de desteklerRazor.Razor

Uygulama

Filtreler, farklı arabirim tanımları aracılığıyla hem zaman uyumlu hem de zaman uyumsuz uygulamaları destekler.

Zaman uyumlu filtreler işlem hattı aşamasından önce ve sonra çalışır. Örneğin, OnActionExecuting eylem yöntemi çağrılmadan önce çağrılır. OnActionExecuted , eylem yöntemi döndürdüğünde çağrılır:

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

Zaman uyumsuz filtreler bir On-Stage-ExecutionAsync yöntem tanımlar. Örneğin, OnActionExecutionAsync:

public class SampleAsyncActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(
        ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // Do something before the action executes.
        await next();
        // Do something after the action executes.
    }
}

Yukarıdaki kodda SampleAsyncActionFilter , eylem yöntemini yürüten bir ActionExecutionDelegate, nextvardır.

Birden çok filtre aşaması

Birden çok filtre aşaması için arabirimler tek bir sınıfta uygulanabilir. Örneğin, ActionFilterAttribute sınıfı şunları uygular:

Her ikisini birden değil, bir filtre arabiriminin zaman uyumlu veya zaman uyumsuz sürümünü uygulayın. Çalışma zamanı ö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. Hem zaman uyumsuz hem de zaman uyumlu arabirimler bir sınıfta uygulanırsa, yalnızca zaman uyumsuz yöntem çağrılır. gibi ActionFilterAttributesoyut sınıfları kullanırken, her filtre türü için yalnızca zaman uyumlu yöntemleri veya zaman uyumsuz yöntemleri geçersiz kılın.

Yerleşik filtre öznitelikleri

ASP.NET Core, alt sınıfa alınabilen ve özelleştirilebilen yerleşik öznitelik tabanlı filtreler içerir. Örneğin, aşağıdaki sonuç filtresi yanıta bir üst bilgi ekler:

public class ResponseHeaderAttribute : ActionFilterAttribute
{
    private readonly string _name;
    private readonly string _value;

    public ResponseHeaderAttribute(string name, string value) =>
        (_name, _value) = (name, value);

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add(_name, _value);

        base.OnResultExecuting(context);
    }
}

Öznitelikler, önceki örnekte gösterildiği gibi filtrelerin bağımsız değişkenleri kabul etmelerine izin verir. öğesini ResponseHeaderAttribute bir denetleyiciye veya eylem yöntemine uygulayın ve HTTP üst bilgisinin adını ve değerini belirtin:

[ResponseHeader("Filter-Header", "Filter Value")]
public class ResponseHeaderController : ControllerBase
{
    public IActionResult Index() =>
        Content("Examine the response headers using the F12 developer tools.");

    // ...

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

Aşağıdaki kod hem denetleyici hem de eylem için geçerlidir ResponseHeaderAttribute :

[ResponseHeader("Filter-Header", "Filter Value")]
public class ResponseHeaderController : ControllerBase
{
    public IActionResult Index() =>
        Content("Examine the response headers using the F12 developer tools.");

    // ...

    [ResponseHeader("Another-Filter-Header", "Another Filter Value")]
    public IActionResult Multiple() =>
        Content("Examine the response headers using the F12 developer tools.");
}

Eylemden alınan Multiple yanıtlar aşağıdaki üst bilgileri içerir:

  • filter-header: Filter Value
  • another-filter-header: Another Filter Value

Filtre arabirimlerinin birkaçı, özel uygulamalar için temel sınıflar olarak kullanılabilecek ilgili özniteliklere sahiptir.

Filtre öznitelikleri:

Filtreler Sayfa işleyici yöntemlerine Razor uygulanamaz. Bunlar Sayfa modeline Razor veya genel olarak uygulanabilir.

Filtre kapsamları ve yürütme sırası

İşlem hattına üç kapsamdan birine filtre eklenebilir:

  • Denetleyicide veya Razor Sayfada bir öznitelik kullanma.
  • Denetleyici eyleminde öznitelik kullanma. Filtre öznitelikleri Sayfalar işleyici yöntemlerine Razor uygulanamaz.
  • Aşağıdaki kodda gösterildiği gibi tüm denetleyiciler, eylemler ve Razor Sayfalar için genel olarak:
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.AddControllersWithViews(options =>
    {
        options.Filters.Add<GlobalSampleActionFilter>();
    });
    

Varsayılan yürütme sırası

İşlem hattının belirli bir aşaması için birden çok filtre olduğunda kapsam varsayılan filtre yürütme sırasını belirler. Genel filtreler sınıf filtrelerini çevreler ve bu da yöntem filtrelerini çevreler.

Filtre iç içe yerleştirmenin bir sonucu olarak, filtrelerden sonraki kod, önceki kodun ters sırasına göre çalışır. Filtre sırası:

  • Genel filtrelerin önceki kodu.
    • Denetleyicinin önceki kodu filtreleri.
      • Önceki eylem yöntemi kodu filtreler.
      • Eylemden sonraki kod yöntemi filtreler.
    • Denetleyicinin after kodu filtreleri.
  • Genel filtrelerin after kodu.

Aşağıdaki örnekte, zaman uyumlu eylem filtreleri için filtre yöntemlerinin çalışma sırası gösterilmektedir:

Sequence Filtre kapsamı Filter yöntemi
Kategori 1 Global OnActionExecuting
2 Oyun kumandası OnActionExecuting
3 Eylem OnActionExecuting
4 Eylem OnActionExecuted
5 Oyun kumandası OnActionExecuted
6 Global OnActionExecuted

Denetleyici düzeyi filtreleri

öğesinden Controller devralan her denetleyici , OnActionExecutionAsyncve OnActionExecuted yöntemlerini içerirOnActionExecuting. Bu yöntemler, belirli bir eylem için çalışan filtreleri sarmalar:

  • OnActionExecuting eylemin filtrelerinden önce çalışır.
  • OnActionExecuted eylemin tüm filtrelerinden sonra çalışır.
  • OnActionExecutionAsync eylemin filtrelerinden önce çalışır. Eylemin filtrelerinin ardından çalıştırılan next bir çağrıdan sonra kod.

Aşağıdaki ControllerFiltersController sınıf:

  • denetleyiciye SampleActionFilterAttribute ([SampleActionFilter]) uygular.
  • ve OnActionExecutedgeçersiz kılmalarıOnActionExecuting.
[SampleActionFilter]
public class ControllerFiltersController : Controller
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine(
            $"- {nameof(ControllerFiltersController)}.{nameof(OnActionExecuting)}");

        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine(
            $"- {nameof(ControllerFiltersController)}.{nameof(OnActionExecuted)}");

        base.OnActionExecuted(context);
    }

    public IActionResult Index()
    {
        Console.WriteLine(
            $"- {nameof(ControllerFiltersController)}.{nameof(Index)}");

        return Content("Check the Console.");
    }
}

Gezinmek için https://localhost:<port>/ControllerFilters aşağıdaki kodu çalıştırın:

  • ControllerFiltersController.OnActionExecuting
    • GlobalSampleActionFilter.OnActionExecuting
      • SampleActionFilterAttribute.OnActionExecuting
        • ControllerFiltersController.Index
      • SampleActionFilterAttribute.OnActionExecuted
    • GlobalSampleActionFilter.OnActionExecuted
  • ControllerFiltersController.OnActionExecuted

Denetleyici düzeyi filtreleri Order özelliğini olarak int.MinValueayarlar. Denetleyici düzeyi filtreleri , yöntemlere filtre uygulandıktan sonra çalışacak şekilde ayarlanamaz . Sipariş, sonraki bölümde açıklanmıştır.

Sayfalar için Razor bkz. Filtre yöntemlerini geçersiz kılarak Sayfa filtrelerini uygulamaRazor.

Varsayılan sırayı geçersiz kılma

varsayılan yürütme dizisi uygulanarak IOrderedFiltergeçersiz kılınabilir. IOrderedFilterOrder yürütme sırasını belirlemek için kapsam üzerinde öncelikli olan özelliğini kullanıma sunar. Daha düşük Order değere sahip bir filtre:

  • daha yüksek değere Ordersahip bir filtrenin önceki kodunu çalıştırır.
  • Daha yüksek Order bir değere sahip bir filtreden sonraki kodu çalıştırır.

Denetleyici düzeyi filtreleri örneğinde, GlobalSampleActionFilter denetleyici kapsamına sahip olan öncesinde SampleActionFilterAttributeçalışması için genel kapsama sahiptir. İlk çalıştırmayı yapmak SampleActionFilterAttribute için sırasını olarak int.MinValueayarlayın:

[SampleActionFilter(Order = int.MinValue)]
public class ControllerFiltersController : Controller
{
    // ...
}

Önce genel filtrenin GlobalSampleActionFilter çalıştırılmasını sağlamak için, öğesini Order olarak int.MinValueayarlayın:

builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<GlobalSampleActionFilter>(int.MinValue);
});

İptal ve kısa devre

Filtre işlem hattı, filtre yöntemine Result sağlanan parametrede ResourceExecutingContext özelliği ayarlanarak kısa devre yapılabilir. Örneğin, aşağıdaki Kaynak filtresi işlem hattının geri kalanının yürütülmesini engeller:

public class ShortCircuitingResourceFilterAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        context.Result = new ContentResult
        {
            Content = nameof(ShortCircuitingResourceFilterAttribute)
        };
    }

    public void OnResourceExecuted(ResourceExecutedContext context) { }
}

Aşağıdaki kodda, hem hem de [ShortCircuitingResourceFilter][ResponseHeader] filtresi eylem yöntemini hedefler Index . Filtre ShortCircuitingResourceFilterAttribute :

  • Önce çalışır çünkü bu bir Kaynak Filtresi ve ResponseHeaderAttribute bir Eylem Filtresidir.
  • İşlem hattının geri kalanını kısa devreler.

Bu nedenle ResponseHeaderAttribute , filtre hiçbir zaman eylem için Index çalıştırılır. Bu davranış, her iki filtre de önce çalıştırılan ShortCircuitingResourceFilterAttribute eylem yöntemi düzeyinde uygulanmışsa aynı olacaktır. Filtre ShortCircuitingResourceFilterAttribute türü nedeniyle ilk olarak çalıştırılır:

[ResponseHeader("Filter-Header", "Filter Value")]
public class ShortCircuitingController : Controller
{
    [ShortCircuitingResourceFilter]
    public IActionResult Index() =>
        Content($"- {nameof(ShortCircuitingController)}.{nameof(Index)}");
}

Bağımlılık ekleme

Filtreler türe veya örneğe göre eklenebilir. Bir örnek eklenirse, bu örnek her istek için kullanılır. Bir tür eklenirse, tür etkinleştirilir. Tür etkinleştirilmiş filtre şu anlama gelir:

  • Her istek için bir örnek oluşturulur.
  • Tüm oluşturucu bağımlılıkları bağımlılık ekleme (DI) ile doldurulur.

Öznitelik olarak uygulanan ve doğrudan denetleyici sınıflarına veya eylem yöntemlerine eklenen filtrelerin bağımlılık ekleme (DI) tarafından sağlanan oluşturucu bağımlılıkları olamaz. Özniteliklerin uygulandıkları yerde oluşturucu parametrelerinin sağlanması gerektiğinden, oluşturucu bağımlılıkları DI tarafından sağlanamaz.

Aşağıdaki filtreler DI'den sağlanan oluşturucu bağımlılıklarını destekler:

Yukarıdaki filtreler bir denetleyiciye veya bir eyleme uygulanabilir.

Günlükçüler DI'den kullanılabilir. Ancak, filtreleri yalnızca günlüğe kaydetme amacıyla oluşturmaktan ve kullanmaktan kaçının. Yerleşik çerçeve günlüğü genellikle günlüğe kaydetme için gerekenleri sağlar. Filtrelere eklenen günlüğe kaydetme:

  • İş etki alanı endişelerine veya filtreye özgü davranışlara odaklanmalıdır.
  • Eylemleri veya diğer çerçeve olaylarını günlüğe kaydetmemelidir. Yerleşik filtreler zaten eylemleri ve çerçeve olaylarını günlüğe kaydeder.

ServiceFilterAttribute

Hizmet filtresi uygulama türleri içinde Program.cskaydedilir. A ServiceFilterAttribute , DI'den filtrenin bir örneğini alır.

Aşağıdaki kod, DI kullanan sınıfını gösterir LoggingResponseHeaderFilterService :

public class LoggingResponseHeaderFilterService : IResultFilter
{
    private readonly ILogger _logger;

    public LoggingResponseHeaderFilterService(
            ILogger<LoggingResponseHeaderFilterService> logger) =>
        _logger = logger;

    public void OnResultExecuting(ResultExecutingContext context)
    {
        _logger.LogInformation(
            $"- {nameof(LoggingResponseHeaderFilterService)}.{nameof(OnResultExecuting)}");

        context.HttpContext.Response.Headers.Add(
            nameof(OnResultExecuting), nameof(LoggingResponseHeaderFilterService));
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        _logger.LogInformation(
            $"- {nameof(LoggingResponseHeaderFilterService)}.{nameof(OnResultExecuted)}");
    }
}

Aşağıdaki kodda DI LoggingResponseHeaderFilterService kapsayıcısına eklenir:

builder.Services.AddScoped<LoggingResponseHeaderFilterService>();

Aşağıdaki kodda ServiceFilter özniteliği, DI'den filtrenin LoggingResponseHeaderFilterService bir örneğini alır:

[ServiceFilter<LoggingResponseHeaderFilterService>]
public IActionResult WithServiceFilter() =>
    Content($"- {nameof(FilterDependenciesController)}.{nameof(WithServiceFilter)}");

kullanırken ServiceFilterAttributeayarı ServiceFilterAttribute.IsReusable:

  • Filtre örneğinin , içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin bir ipucu sağlar. ASP.NET Core çalışma zamanı aşağıdakileri garanti etmez:
    • Filtrenin tek bir örneğinin oluşturulacağı.
    • Filtre daha sonraki bir noktada DI kapsayıcısından yeniden istenmeyecek.
  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

ServiceFilterAttribute uygular IFilterFactory. IFilterFactoryCreateInstance örneği oluşturmak IFilterMetadata için yöntemini kullanıma sunar. CreateInstance belirtilen türü DI'den yükler.

TypeFilterAttribute

TypeFilterAttribute ile benzerdir ServiceFilterAttribute, ancak türü doğrudan DI kapsayıcısından çözümlenmez. kullanarak türün örneğini oluşturur Microsoft.Extensions.DependencyInjection.ObjectFactory.

Türler TypeFilterAttribute doğrudan DI kapsayıcısından çözümlenmediğinden:

  • kullanılarak TypeFilterAttribute başvurulan türlerin DI kapsayıcısına kaydedilmesi gerekmez. Di kapsayıcısı tarafından karşılanan bağımlılıkları vardır.
  • TypeFilterAttribute isteğe bağlı olarak tür için oluşturucu bağımsız değişkenlerini kabul edebilir.

kullanırken TypeFilterAttributeayarı TypeFilterAttribute.IsReusable:

  • Filtre örneğinin , içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin ipucu sağlar. ASP.NET Core çalışma zamanı, filtrenin tek bir örneğinin oluşturulacağını garanti eder.

  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

Aşağıdaki örnekte kullanarak TypeFilterAttributebağımsız değişkenlerin bir türe nasıl geçir kullanıldığı gösterilmektedir:

[TypeFilter(typeof(LoggingResponseHeaderFilter),
    Arguments = new object[] { "Filter-Header", "Filter Value" })]
public IActionResult WithTypeFilter() =>
    Content($"- {nameof(FilterDependenciesController)}.{nameof(WithTypeFilter)}");

Yetkilendirme filtreleri

Yetkilendirme filtreleri:

  • İlk filtreler filtre işlem hattında çalıştırılır.
  • Eylem yöntemlerine erişimi denetleme.
  • Önce yöntemine sahip olun, ancak sonra yöntemi yok.

Özel yetkilendirme filtreleri için özel yetkilendirme çerçevesi gerekir. Özel filtre yazmak yerine yetkilendirme ilkelerini yapılandırmayı veya özel yetkilendirme ilkesi yazmayı tercih edin. Yerleşik yetkilendirme filtresi:

  • Yetkilendirme sistemini çağırır.
  • İstekleri yetkilendirmez.

Yetkilendirme filtrelerinde özel durumlar oluşturmayın:

  • Özel durum işlenmez.
  • Özel durum filtreleri özel durumu işlemez.

Yetkilendirme filtresinde bir özel durum oluştuğunda bir sınama vermeyi göz önünde bulundurun.

Yetkilendirme hakkında daha fazla bilgi edinin.

Kaynak filtreleri

Kaynak filtreleri:

Kaynak filtreleri, işlem hattının büyük bölümünü kısa devre yapmak için kullanışlıdır. Örneğin, önbelleğe alma filtresi önbellek isabetinde işlem hattının geri kalanını önleyebilir.

Kaynak filtresi örnekleri:

Eylem filtreleri

Eylem filtreleri Sayfalar'a Razor uygulanmaz. RazorSayfalar ve'i IAsyncPageFilterdesteklerIPageFilter. Daha fazla bilgi için bkz. Sayfalar için Razor filtreleme yöntemleri.

Eylem filtreleri:

Aşağıdaki kodda örnek bir eylem filtresi gösterilmektedir:

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

ActionExecutingContext aşağıdaki özellikleri sağlar:

  • ActionArguments - bir eylem yöntemine girişlerin okunmasını sağlar.
  • Controller - denetleyici örneğinin manipülesini etkinleştirir.
  • Result - eylem yönteminin ve sonraki eylem filtrelerinin kısa devre yürütmesini ayarlama Result .

Bir eylem yönteminde özel durum oluşturma:

  • Sonraki filtrelerin çalıştırılmasını engeller.
  • ayarından Resultfarklı olarak, başarılı bir sonuç yerine bir hata olarak değerlendirilir.

ActionExecutedContext ve Result artı olarak aşağıdaki özellikleri sağlarController:

  • Canceled - Eylem yürütmesi başka bir filtre tarafından kısa devreliyse true.
  • Exception - Eylem veya daha önce çalıştırmış bir eylem filtresi özel durum oluşturduysa null olmayan. Bu özellik null olarak ayarlanıyor:
    • Özel durumu etkili bir şekilde işler.
    • Result , eylem yönteminden döndürülür gibi yürütülür.

için IAsyncActionFilteröğesine yönelik bir çağrı:ActionExecutionDelegate

  • Sonraki tüm eylem filtrelerini ve eylem yöntemini yürütür.
  • ActionExecutedContext döndürür.

Kısa devre için, bir sonuç örneğine atayın Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.ResultActionExecutionDelegateve (çağırmayın next ).

Çerçeve, alt sınıflandırılabilir bir soyut ActionFilterAttribute sağlar.

Eylem OnActionExecuting filtresi aşağıdakileri yapmak için kullanılabilir:

  • Model durumunu doğrulayın.
  • Durum geçersizse bir hata döndürür.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }
}

Dekont

Özniteliğiyle [ApiController] açıklama eklenmiş denetleyiciler model durumunu otomatik olarak doğrular ve 400 yanıtı döndürür. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

yöntemi, OnActionExecuted eylem yönteminden sonra çalışır:

  • Ve özelliği aracılığıyla Result eylemin sonuçlarını görebilir ve işleyebilir.
  • Canceled eylem yürütmesi başka bir filtre tarafından kısa devreliyse true olarak ayarlanır.
  • Exception , eylem veya sonraki bir eylem filtresi özel durum oluşturduysa null olmayan bir değere ayarlanır. Null olarak ayarlanıyor Exception :
    • Bir özel durumu etkili bir şekilde işler.
    • ActionExecutedContext.Result , eylem yönteminden normal şekilde döndürülür gibi yürütülür.

Özel durum filtreleri

Özel durum filtreleri:

Aşağıdaki örnek özel durum filtresi, uygulama geliştirme aşamasındayken oluşan özel durumlar hakkındaki ayrıntıları görüntüler:

public class SampleExceptionFilter : IExceptionFilter
{
    private readonly IHostEnvironment _hostEnvironment;

    public SampleExceptionFilter(IHostEnvironment hostEnvironment) =>
        _hostEnvironment = hostEnvironment;

    public void OnException(ExceptionContext context)
    {
        if (!_hostEnvironment.IsDevelopment())
        {
            // Don't display exception details unless running in Development.
            return;
        }

        context.Result = new ContentResult
        {
            Content = context.Exception.ToString()
        };
    }
}

Aşağıdaki kod özel durum filtresini test ediyor:

[TypeFilter<SampleExceptionFilter>]
public class ExceptionController : Controller
{
    public IActionResult Index() =>
        Content($"- {nameof(ExceptionController)}.{nameof(Index)}");
}

Özel durum filtreleri:

  • Etkinlik öncesi ve sonrası yok.
  • veya OnExceptionAsyncuygulayınOnException.
  • Sayfa veya denetleyici oluşturma, model bağlama, eylem filtreleri veya eylem yöntemlerinde Razor oluşan işlenmeyen özel durumları işleyin.
  • Kaynak filtrelerinde, sonuç filtrelerinde veya MVC sonuç yürütmesinde oluşan özel durumları yakalamayın.

Bir özel durumu işlemek için özelliğini olarak true ayarlayın ExceptionHandled veya özelliğini atayınResult. Bu, özel durumun yayılmasını durdurur. Özel durum filtresi bir özel durumu "başarılı" duruma getiremez. Bunu yalnızca bir eylem filtresi yapabilir.

Özel durum filtreleri:

  • Eylemler içinde oluşan özel durumları yakalamak için iyidir.
  • Hata işleme ara yazılımı kadar esnek değildir.

Özel durum işleme için ara yazılımı tercih edin. Özel durum filtrelerini yalnızca hata işlemenin hangi eylem yönteminin çağrıldığı temelinde farklı olduğu durumlarda kullanın. Örneğin, bir uygulamanın hem API uç noktaları hem de görünümler/HTML için eylem yöntemleri olabilir. API uç noktaları hata bilgilerini ON olarak JSdöndürebilirken, görünüm tabanlı eylemler html olarak bir hata sayfası döndürebilir.

Sonuç filtreleri

Sonuç filtreleri:

IResultFilter ve IAsyncResultFilter

Aşağıdaki kodda örnek bir sonuç filtresi gösterilmektedir:

public class SampleResultFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        // Do something before the result executes.
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Do something after the result executes.
    }
}

Yürütülen sonuç türü eyleme bağlıdır. Görünüm döndüren eylem, yürütülmekte olan ViewResult tüm razor işlemlerini içerir. BIR API yöntemi, sonucun yürütülmesinin bir parçası olarak bazı serileştirmeler gerçekleştirebilir. Eylem sonuçları hakkında daha fazla bilgi edinin.

Sonuç filtreleri yalnızca bir eylem veya eylem filtresi bir eylem sonucu ürettiğinde yürütülür. Sonuç filtreleri şu durumlarda yürütülür:

  • Yetkilendirme filtresi veya kaynak filtresi işlem hattını kısa devrelere bağlar.
  • Özel durum filtresi, bir eylem sonucu oluşturarak özel durumu işler.

yöntemi, Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting olarak ayarlayarak Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel eylem sonucunun ve sonraki sonuç filtrelerinin kısa devre yürütmesini truesağlayabilir. Boş yanıt oluşturmamak için kısa devre yaparken yanıt nesnesine yazın. içinde IResultFilter.OnResultExecutingözel durum oluşturma:

  • Eylem sonucunun ve sonraki filtrelerin yürütülmesini engeller.
  • Başarılı bir sonuç yerine hata olarak değerlendirilir.

Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted Yöntem çalıştırıldığında, yanıt büyük olasılıkla istemciye gönderilmiştir. Yanıt istemciye zaten gönderilmişse değiştirilemez.

ResultExecutedContext.Canceled , eylem sonucu yürütmesinin başka bir filtre tarafından kısa devreli olup olmadığını olarak ayarlanır true .

ResultExecutedContext.Exception , eylem sonucu veya sonraki bir sonuç filtresi özel durum oluşturduysa null olmayan bir değere ayarlanır. null ayarı Exception bir özel durumu etkili bir şekilde işler ve özel durumun işlem hattında daha sonra yeniden oluşmasını önler. Sonuç filtresinde özel durum işlenirken yanıta veri yazmanın güvenilir bir yolu yoktur. Bir eylem sonucu özel durum oluştururken üst bilgiler istemciye boşaltıldıysa, hata kodu göndermek için güvenilir bir mekanizma yoktur.

bir IAsyncResultFilteriçin, üzerindeki ResultExecutionDelegate çağrısı await next sonraki tüm sonuç filtrelerini ve eylem sonucunu yürütür. Kısa devre için olarak ayarlayın ResultExecutingContext.Canceltrue ve çağrısı ResultExecutionDelegateyapmayın:

public class SampleAsyncResultFilter : IAsyncResultFilter
{
    public async Task OnResultExecutionAsync(
        ResultExecutingContext context, ResultExecutionDelegate next)
    {
        if (context.Result is not EmptyResult)
        {
            await next();
        }
        else
        {
            context.Cancel = true;
        }
    }
}

Çerçeve, alt sınıflandırılabilir bir soyut ResultFilterAttribute sağlar. Daha önce gösterilen ResponseHeaderAttribute sınıfı bir sonuç filtresi özniteliği örneğidir.

IAlwaysRunResultFilter ve IAsyncAlwaysRunResultFilter

IAlwaysRunResultFilter ve IAsyncAlwaysRunResultFilter arabirimleri, tüm eylem sonuçları için çalışan bir IResultFilter uygulama bildirir. Bu, tarafından üretilen eylem sonuçlarını içerir:

  • Yetkilendirme filtreleri ve kısa devreli kaynak filtreleri.
  • Özel durum filtreleri.

Örneğin, aşağıdaki filtre her zaman çalışır ve içerik anlaşması başarısız olduğunda 422 İşlenemez Varlık durum koduyla bir eylem sonucu (ObjectResult) ayarlar:

public class UnprocessableResultFilter : IAlwaysRunResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is StatusCodeResult statusCodeResult
            && statusCodeResult.StatusCode == StatusCodes.Status415UnsupportedMediaType)
        {
            context.Result = new ObjectResult("Unprocessable")
            {
                StatusCode = StatusCodes.Status422UnprocessableEntity
            };
        }
    }

    public void OnResultExecuted(ResultExecutedContext context) { }
}

IFilterFactory

IFilterFactory uygular IFilterMetadata. Bu nedenle, bir IFilterFactory örnek filtre işlem hattının herhangi bir IFilterMetadata yerinde örnek olarak kullanılabilir. Çalışma zamanı filtreyi çağırmaya hazırlandığında, bunu bir IFilterFactoryöğesine dönüştürmeye çalışır. Bu atama başarılı olursa, CreateInstance çağrılan örneği oluşturmak IFilterMetadata için yöntemi çağrılır. Bu esnek bir tasarım sağlar, çünkü uygulama başlatıldığında hassas filtre işlem hattının açıkça ayarlanması gerekmez.

IFilterFactory.IsReusable:

  • Fabrika tarafından oluşturulan filtre örneğinin, içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin bir ipucudur.
  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

ASP.NET Core çalışma zamanı aşağıdakileri garanti etmez:

  • Filtrenin tek bir örneğinin oluşturulacağı.
  • Filtre daha sonraki bir noktada DI kapsayıcısından yeniden istenmeyecek.

Uyarı

Yalnızca filtrelerin kaynağı belirsizse, filtreler durum bilgisi yoksa ve filtrelerin birden çok HTTP isteğinde kullanılması güvenliyse döndürülecek true şekilde yapılandırınIFilterFactory.IsReusable. Örneğin, kapsamı belirlenmiş veya döndürürse IFilterFactory.IsReusable geçici olarak kaydedilen DI filtrelerini döndürmeyin true.

IFilterFactory filtre oluşturmaya yönelik başka bir yaklaşım olarak özel öznitelik uygulamaları kullanılarak uygulanabilir:

public class ResponseHeaderFilterFactory : Attribute, IFilterFactory
{
    public bool IsReusable => false;

    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) =>
        new InternalResponseHeaderFilter();

    private class InternalResponseHeaderFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context) =>
            context.HttpContext.Response.Headers.Add(
                nameof(OnActionExecuting), nameof(InternalResponseHeaderFilter));

        public void OnActionExecuted(ActionExecutedContext context) { }
    }

Filtre aşağıdaki kodda uygulanır:

[ResponseHeaderFilterFactory]
public IActionResult Index() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(Index)}");

Bir öznitelikte uygulanan IFilterFactory

Uygulayan IFilterFactory filtreler, aşağıdaki filtreler için kullanışlıdır:

  • Parametrelerin geçirilmesini gerektirmez.
  • DI tarafından doldurulması gereken oluşturucu bağımlılıkları vardır.

TypeFilterAttribute uygular IFilterFactory. IFilterFactoryCreateInstance örneği oluşturmak IFilterMetadata için yöntemini kullanıma sunar. CreateInstance , belirtilen türü services kapsayıcısından (DI) yükler.

public class SampleActionTypeFilterAttribute : TypeFilterAttribute
{
    public SampleActionTypeFilterAttribute()
         : base(typeof(InternalSampleActionFilter)) { }

    private class InternalSampleActionFilter : IActionFilter
    {
        private readonly ILogger<InternalSampleActionFilter> _logger;

        public InternalSampleActionFilter(ILogger<InternalSampleActionFilter> logger) =>
            _logger = logger;

        public void OnActionExecuting(ActionExecutingContext context)
        {
            _logger.LogInformation(
                $"- {nameof(InternalSampleActionFilter)}.{nameof(OnActionExecuting)}");
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            _logger.LogInformation(
                $"- {nameof(InternalSampleActionFilter)}.{nameof(OnActionExecuted)}");
        }
    }
}

Aşağıdaki kod, filtreyi uygulamak için üç yaklaşım gösterir:

[SampleActionTypeFilter]
public IActionResult WithDirectAttribute() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(WithDirectAttribute)}");

[TypeFilter<SampleActionTypeFilterAttribute>]
public IActionResult WithTypeFilterAttribute() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(WithTypeFilterAttribute)}");

[ServiceFilter<SampleActionTypeFilterAttribute>]
public IActionResult WithServiceFilterAttribute() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(WithServiceFilterAttribute)}");

Yukarıdaki kodda, filtreyi uygulamak için ilk yaklaşım tercih edilir.

Filtre işlem hattında ara yazılım kullanma

Kaynak filtreleri, işlem hattında daha sonra gelen her şeyin yürütülmesini çevreleyen ara yazılım gibi çalışır. Ancak filtreler, çalışma zamanının parçası oldukları için ara yazılımdan farklıdır ve bu da bağlam ve yapılara erişimleri olduğu anlamına gelir.

Ara yazılımı filtre olarak kullanmak için, filtre işlem hattına eklenecek ara yazılımı belirten bir yönteme sahip bir Configure tür oluşturun. Aşağıdaki örnek, yanıt üst bilgisini ayarlamak için ara yazılımı kullanır:

public class FilterMiddlewarePipeline
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            context.Response.Headers.Add("Pipeline", "Middleware");

            await next();
        });
    }
}

Ara yazılımı çalıştırmak için öğesini MiddlewareFilterAttribute kullanın:

[MiddlewareFilter<FilterMiddlewarePipeline>]
public class FilterMiddlewareController : Controller
{
    public IActionResult Index() =>
        Content($"- {nameof(FilterMiddlewareController)}.{nameof(Index)}");
}

Ara yazılım filtreleri, filtre işlem hattının Kaynak filtreleri ile aynı aşamasında, model bağlamadan önce ve işlem hattının geri kalanından sonra çalışır.

İş parçacığı güvenliği

Filtrenin bir örneğini yerine içine TypeAddgeçirirken, filtre tekildir ve iş parçacığı açısından güvenli değildir.

Ek kaynaklar

Kirk Larkin, Rick Anderson, Tom Dykstra ve Steve Smith tarafından

ASP.NET Core'daki filtreler , kodun istek işleme işlem hattındaki belirli aşamaların öncesinde veya sonrasında çalıştırılmasına olanak sağlar.

Yerleşik filtreler şunlar gibi görevleri işler:

  • Yetkilendirme, kullanıcının yetkilendirilmemiş kaynaklara erişimini engelleme.
  • Yanıt önbelleğe alma, önbelleğe alınmış bir yanıt döndürmek için istek işlem hattını kısa devreden geçirme.

Çapraz kesme sorunlarını çözmek için özel filtreler oluşturulabilir. Çapraz kesme endişelerine örnek olarak hata işleme, önbelleğe alma, yapılandırma, yetkilendirme ve günlüğe kaydetme verilebilir. Filtreler kodun çoğaltılmasını önler. Örneğin, hata işleme özel durum filtresi hata işlemeyi bir araya gelebilir.

Bu belge Sayfalar, API denetleyicileri ve görünümlere sahip denetleyiciler için Razor geçerlidir. Filtreler bileşenlerle Razordoğrudan çalışmaz. Filtre yalnızca şu durumlarda bir bileşeni dolaylı olarak etkileyebilir:

  • Bileşen bir sayfaya veya görünüme eklenir.
  • Sayfa veya denetleyici ve görünüm filtreyi kullanır.

Filtreler nasıl çalışır?

Filtreler, bazen filtre işlem hattı olarak da adlandırılan ASP.NET Core eylem çağırma işlem hattı içinde çalışır. Filtre işlem hattı, ASP.NET Core yürütülecek eylemi seçtikten sonra çalışır:

The request is processed through Other Middleware, Routing Middleware, Action Selection, and the Action Invocation Pipeline. The request processing continues back through Action Selection, Routing Middleware, and various Other Middleware before becoming a response sent to the client.

Filtre türleri

Her filtre türü, filtre işlem hattında farklı bir aşamada yürütülür:

  • Yetkilendirme filtreleri:

    • önce çalıştırın.
    • Kullanıcının istek için yetkilendirilip yetkilendirilmediğini belirleyin.
    • İstek yetkilendirilmediyse işlem hattını kısa devreye geçirin.
  • Kaynak filtreleri:

    • Yetkilendirmeden sonra çalıştırın.
    • OnResourceExecuting filtre işlem hattının geri kalanından önce kodu çalıştırır. Örneğin, OnResourceExecuting model bağlamadan önce kodu çalıştırır.
    • OnResourceExecuted işlem hattının geri kalanı tamamlandıktan sonra kodu çalıştırır.
  • Eylem filtreleri:

    • Bir eylem yöntemi çağrılmadan hemen önce ve sonra çalıştırın.
    • Bir eyleme geçirilen bağımsız değişkenleri değiştirebilir.
    • Eylemden döndürülen sonucu değiştirebilir.
    • Sayfalar'da Razor desteklenmez.
  • Uç nokta filtreleri:

    • Bir eylem yöntemi çağrılmadan hemen önce ve sonra çalıştırın.
    • Bir eyleme geçirilen bağımsız değişkenleri değiştirebilir.
    • Eylemden döndürülen sonucu değiştirebilir.
    • Sayfalar'da Razor desteklenmez.
    • Hem eylemlerde hem de yol işleyici tabanlı uç noktalarda çağrılabilir.
  • Özel durum filtreleri , yanıt gövdesi yazılmadan önce gerçekleşen işlenmeyen özel durumlara genel ilkeler uygular.

  • Sonuç filtreleri:

    • Eylem sonuçlarının yürütülmesinden hemen önce ve sonra çalıştırın.
    • Yalnızca eylem yöntemi başarıyla yürütürken çalıştırın.
    • Görünüm veya biçimlendirici yürütmeyi çevrelemesi gereken mantık için kullanışlıdır.

Aşağıdaki diyagramda filtre türlerinin filtre işlem hattında nasıl etkileşimde olduğu gösterilmektedir:

The request is processed through Authorization Filters, Resource Filters, Model Binding, Action Filters, Action Execution and Action Result Conversion, Exception Filters, Result Filters, and Result Execution. On the way out, the request is only processed by Result Filters and Resource Filters before becoming a response sent to the client.

RazorSayfalar, Sayfa işleyiciden önce ve sonra çalışan Sayfa filtrelerini de desteklerRazor.Razor

Uygulama

Filtreler, farklı arabirim tanımları aracılığıyla hem zaman uyumlu hem de zaman uyumsuz uygulamaları destekler.

Zaman uyumlu filtreler işlem hattı aşamasından önce ve sonra çalışır. Örneğin, OnActionExecuting eylem yöntemi çağrılmadan önce çağrılır. OnActionExecuted , eylem yöntemi döndürdüğünde çağrılır:

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

Zaman uyumsuz filtreler bir On-Stage-ExecutionAsync yöntem tanımlar. Örneğin, OnActionExecutionAsync:

public class SampleAsyncActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(
        ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // Do something before the action executes.
        await next();
        // Do something after the action executes.
    }
}

Yukarıdaki kodda SampleAsyncActionFilter , eylem yöntemini yürüten bir ActionExecutionDelegate, nextvardır.

Birden çok filtre aşaması

Birden çok filtre aşaması için arabirimler tek bir sınıfta uygulanabilir. Örneğin, ActionFilterAttribute sınıfı şunları uygular:

Her ikisini birden değil, bir filtre arabiriminin zaman uyumlu veya zaman uyumsuz sürümünü uygulayın. Çalışma zamanı ö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. Hem zaman uyumsuz hem de zaman uyumlu arabirimler bir sınıfta uygulanırsa, yalnızca zaman uyumsuz yöntem çağrılır. gibi ActionFilterAttributesoyut sınıfları kullanırken, her filtre türü için yalnızca zaman uyumlu yöntemleri veya zaman uyumsuz yöntemleri geçersiz kılın.

Yerleşik filtre öznitelikleri

ASP.NET Core, alt sınıfa alınabilen ve özelleştirilebilen yerleşik öznitelik tabanlı filtreler içerir. Örneğin, aşağıdaki sonuç filtresi yanıta bir üst bilgi ekler:

public class ResponseHeaderAttribute : ActionFilterAttribute
{
    private readonly string _name;
    private readonly string _value;

    public ResponseHeaderAttribute(string name, string value) =>
        (_name, _value) = (name, value);

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add(_name, _value);

        base.OnResultExecuting(context);
    }
}

Öznitelikler, önceki örnekte gösterildiği gibi filtrelerin bağımsız değişkenleri kabul etmelerine izin verir. öğesini ResponseHeaderAttribute bir denetleyiciye veya eylem yöntemine uygulayın ve HTTP üst bilgisinin adını ve değerini belirtin:

[ResponseHeader("Filter-Header", "Filter Value")]
public class ResponseHeaderController : ControllerBase
{
    public IActionResult Index() =>
        Content("Examine the response headers using the F12 developer tools.");

    // ...

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

Aşağıdaki kod hem denetleyici hem de eylem için geçerlidir ResponseHeaderAttribute :

[ResponseHeader("Filter-Header", "Filter Value")]
public class ResponseHeaderController : ControllerBase
{
    public IActionResult Index() =>
        Content("Examine the response headers using the F12 developer tools.");

    // ...

    [ResponseHeader("Another-Filter-Header", "Another Filter Value")]
    public IActionResult Multiple() =>
        Content("Examine the response headers using the F12 developer tools.");
}

Eylemden alınan Multiple yanıtlar aşağıdaki üst bilgileri içerir:

  • filter-header: Filter Value
  • another-filter-header: Another Filter Value

Filtre arabirimlerinin birkaçı, özel uygulamalar için temel sınıflar olarak kullanılabilecek ilgili özniteliklere sahiptir.

Filtre öznitelikleri:

Filtreler Sayfa işleyici yöntemlerine Razor uygulanamaz. Bunlar Sayfa modeline Razor veya genel olarak uygulanabilir.

Filtre kapsamları ve yürütme sırası

İşlem hattına üç kapsamdan birine filtre eklenebilir:

  • Denetleyicide veya Razor Sayfada bir öznitelik kullanma.
  • Denetleyici eyleminde öznitelik kullanma. Filtre öznitelikleri Sayfalar işleyici yöntemlerine Razor uygulanamaz.
  • Aşağıdaki kodda gösterildiği gibi tüm denetleyiciler, eylemler ve Razor Sayfalar için genel olarak:
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.AddControllersWithViews(options =>
    {
        options.Filters.Add<GlobalSampleActionFilter>();
    });
    

Varsayılan yürütme sırası

İşlem hattının belirli bir aşaması için birden çok filtre olduğunda kapsam varsayılan filtre yürütme sırasını belirler. Genel filtreler sınıf filtrelerini çevreler ve bu da yöntem filtrelerini çevreler.

Filtre iç içe yerleştirmenin bir sonucu olarak, filtrelerden sonraki kod, önceki kodun ters sırasına göre çalışır. Filtre sırası:

  • Genel filtrelerin önceki kodu.
    • Denetleyicinin önceki kodu filtreleri.
      • Önceki eylem yöntemi kodu filtreler.
      • Eylemden sonraki kod yöntemi filtreler.
    • Denetleyicinin after kodu filtreleri.
  • Genel filtrelerin after kodu.

Aşağıdaki örnekte, zaman uyumlu eylem filtreleri için filtre yöntemlerinin çalışma sırası gösterilmektedir:

Sequence Filtre kapsamı Filter yöntemi
Kategori 1 Global OnActionExecuting
2 Oyun kumandası OnActionExecuting
3 Eylem OnActionExecuting
4 Eylem OnActionExecuted
5 Oyun kumandası OnActionExecuted
6 Global OnActionExecuted

Denetleyici düzeyi filtreleri

öğesinden Controller devralan her denetleyici , OnActionExecutionAsyncve OnActionExecuted yöntemlerini içerirOnActionExecuting. Bu yöntemler, belirli bir eylem için çalışan filtreleri sarmalar:

  • OnActionExecuting eylemin filtrelerinden önce çalışır.
  • OnActionExecuted eylemin tüm filtrelerinden sonra çalışır.
  • OnActionExecutionAsync eylemin filtrelerinden önce çalışır. Eylemin filtrelerinin ardından çalıştırılan next bir çağrıdan sonra kod.

Aşağıdaki ControllerFiltersController sınıf:

  • denetleyiciye SampleActionFilterAttribute ([SampleActionFilter]) uygular.
  • ve OnActionExecutedgeçersiz kılmalarıOnActionExecuting.
[SampleActionFilter]
public class ControllerFiltersController : Controller
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine(
            $"- {nameof(ControllerFiltersController)}.{nameof(OnActionExecuting)}");

        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine(
            $"- {nameof(ControllerFiltersController)}.{nameof(OnActionExecuted)}");

        base.OnActionExecuted(context);
    }

    public IActionResult Index()
    {
        Console.WriteLine(
            $"- {nameof(ControllerFiltersController)}.{nameof(Index)}");

        return Content("Check the Console.");
    }
}

Gezinmek için https://localhost:<port>/ControllerFilters aşağıdaki kodu çalıştırın:

  • ControllerFiltersController.OnActionExecuting
    • GlobalSampleActionFilter.OnActionExecuting
      • SampleActionFilterAttribute.OnActionExecuting
        • ControllerFiltersController.Index
      • SampleActionFilterAttribute.OnActionExecuted
    • GlobalSampleActionFilter.OnActionExecuted
  • ControllerFiltersController.OnActionExecuted

Denetleyici düzeyi filtreleri Order özelliğini olarak int.MinValueayarlar. Denetleyici düzeyi filtreleri , yöntemlere filtre uygulandıktan sonra çalışacak şekilde ayarlanamaz . Sipariş, sonraki bölümde açıklanmıştır.

Sayfalar için Razor bkz. Filtre yöntemlerini geçersiz kılarak Sayfa filtrelerini uygulamaRazor.

Varsayılan sırayı geçersiz kılma

varsayılan yürütme dizisi uygulanarak IOrderedFiltergeçersiz kılınabilir. IOrderedFilterOrder yürütme sırasını belirlemek için kapsam üzerinde öncelikli olan özelliğini kullanıma sunar. Daha düşük Order değere sahip bir filtre:

  • daha yüksek değere Ordersahip bir filtrenin önceki kodunu çalıştırır.
  • Daha yüksek Order bir değere sahip bir filtreden sonraki kodu çalıştırır.

Denetleyici düzeyi filtreleri örneğinde, GlobalSampleActionFilter denetleyici kapsamına sahip olan öncesinde SampleActionFilterAttributeçalışması için genel kapsama sahiptir. İlk çalıştırmayı yapmak SampleActionFilterAttribute için sırasını olarak int.MinValueayarlayın:

[SampleActionFilter(Order = int.MinValue)]
public class ControllerFiltersController : Controller
{
    // ...
}

Önce genel filtrenin GlobalSampleActionFilter çalıştırılmasını sağlamak için, öğesini Order olarak int.MinValueayarlayın:

builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<GlobalSampleActionFilter>(int.MinValue);
});

İptal ve kısa devre

Filtre işlem hattı, filtre yöntemine Result sağlanan parametrede ResourceExecutingContext özelliği ayarlanarak kısa devre yapılabilir. Örneğin, aşağıdaki Kaynak filtresi işlem hattının geri kalanının yürütülmesini engeller:

public class ShortCircuitingResourceFilterAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        context.Result = new ContentResult
        {
            Content = nameof(ShortCircuitingResourceFilterAttribute)
        };
    }

    public void OnResourceExecuted(ResourceExecutedContext context) { }
}

Aşağıdaki kodda, hem hem de [ShortCircuitingResourceFilter][ResponseHeader] filtresi eylem yöntemini hedefler Index . Filtre ShortCircuitingResourceFilterAttribute :

  • Önce çalışır çünkü bu bir Kaynak Filtresi ve ResponseHeaderAttribute bir Eylem Filtresidir.
  • İşlem hattının geri kalanını kısa devreler.

Bu nedenle ResponseHeaderAttribute , filtre hiçbir zaman eylem için Index çalıştırılır. Bu davranış, her iki filtre de önce çalıştırılan ShortCircuitingResourceFilterAttribute eylem yöntemi düzeyinde uygulanmışsa aynı olacaktır. Filtre ShortCircuitingResourceFilterAttribute türü nedeniyle ilk olarak çalıştırılır:

[ResponseHeader("Filter-Header", "Filter Value")]
public class ShortCircuitingController : Controller
{
    [ShortCircuitingResourceFilter]
    public IActionResult Index() =>
        Content($"- {nameof(ShortCircuitingController)}.{nameof(Index)}");
}

Bağımlılık ekleme

Filtreler türe veya örneğe göre eklenebilir. Bir örnek eklenirse, bu örnek her istek için kullanılır. Bir tür eklenirse, tür etkinleştirilir. Tür etkinleştirilmiş filtre şu anlama gelir:

  • Her istek için bir örnek oluşturulur.
  • Tüm oluşturucu bağımlılıkları bağımlılık ekleme (DI) ile doldurulur.

Öznitelik olarak uygulanan ve doğrudan denetleyici sınıflarına veya eylem yöntemlerine eklenen filtrelerin bağımlılık ekleme (DI) tarafından sağlanan oluşturucu bağımlılıkları olamaz. Özniteliklerin uygulandıkları yerde oluşturucu parametrelerinin sağlanması gerektiğinden, oluşturucu bağımlılıkları DI tarafından sağlanamaz.

Aşağıdaki filtreler DI'den sağlanan oluşturucu bağımlılıklarını destekler:

Yukarıdaki filtreler bir denetleyiciye veya bir eyleme uygulanabilir.

Günlükçüler DI'den kullanılabilir. Ancak, filtreleri yalnızca günlüğe kaydetme amacıyla oluşturmaktan ve kullanmaktan kaçının. Yerleşik çerçeve günlüğü genellikle günlüğe kaydetme için gerekenleri sağlar. Filtrelere eklenen günlüğe kaydetme:

  • İş etki alanı endişelerine veya filtreye özgü davranışlara odaklanmalıdır.
  • Eylemleri veya diğer çerçeve olaylarını günlüğe kaydetmemelidir. Yerleşik filtreler zaten eylemleri ve çerçeve olaylarını günlüğe kaydeder.

ServiceFilterAttribute

Hizmet filtresi uygulama türleri içinde Program.cskaydedilir. A ServiceFilterAttribute , DI'den filtrenin bir örneğini alır.

Aşağıdaki kod, DI kullanan sınıfını gösterir LoggingResponseHeaderFilterService :

public class LoggingResponseHeaderFilterService : IResultFilter
{
    private readonly ILogger _logger;

    public LoggingResponseHeaderFilterService(
            ILogger<LoggingResponseHeaderFilterService> logger) =>
        _logger = logger;

    public void OnResultExecuting(ResultExecutingContext context)
    {
        _logger.LogInformation(
            $"- {nameof(LoggingResponseHeaderFilterService)}.{nameof(OnResultExecuting)}");

        context.HttpContext.Response.Headers.Add(
            nameof(OnResultExecuting), nameof(LoggingResponseHeaderFilterService));
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        _logger.LogInformation(
            $"- {nameof(LoggingResponseHeaderFilterService)}.{nameof(OnResultExecuted)}");
    }
}

Aşağıdaki kodda DI LoggingResponseHeaderFilterService kapsayıcısına eklenir:

builder.Services.AddScoped<LoggingResponseHeaderFilterService>();

Aşağıdaki kodda ServiceFilter özniteliği, DI'den filtrenin LoggingResponseHeaderFilterService bir örneğini alır:

[ServiceFilter(typeof(LoggingResponseHeaderFilterService))]
public IActionResult WithServiceFilter() =>
    Content($"- {nameof(FilterDependenciesController)}.{nameof(WithServiceFilter)}");

kullanırken ServiceFilterAttributeayarı ServiceFilterAttribute.IsReusable:

  • Filtre örneğinin , içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin bir ipucu sağlar. ASP.NET Core çalışma zamanı aşağıdakileri garanti etmez:
    • Filtrenin tek bir örneğinin oluşturulacağı.
    • Filtre daha sonraki bir noktada DI kapsayıcısından yeniden istenmeyecek.
  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

ServiceFilterAttribute uygular IFilterFactory. IFilterFactoryCreateInstance örneği oluşturmak IFilterMetadata için yöntemini kullanıma sunar. CreateInstance belirtilen türü DI'den yükler.

TypeFilterAttribute

TypeFilterAttribute ile benzerdir ServiceFilterAttribute, ancak türü doğrudan DI kapsayıcısından çözümlenmez. kullanarak türün örneğini oluşturur Microsoft.Extensions.DependencyInjection.ObjectFactory.

Türler TypeFilterAttribute doğrudan DI kapsayıcısından çözümlenmediğinden:

  • kullanılarak TypeFilterAttribute başvurulan türlerin DI kapsayıcısına kaydedilmesi gerekmez. Di kapsayıcısı tarafından karşılanan bağımlılıkları vardır.
  • TypeFilterAttribute isteğe bağlı olarak tür için oluşturucu bağımsız değişkenlerini kabul edebilir.

kullanırken TypeFilterAttributeayarı TypeFilterAttribute.IsReusable:

  • Filtre örneğinin , içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin ipucu sağlar. ASP.NET Core çalışma zamanı, filtrenin tek bir örneğinin oluşturulacağını garanti eder.

  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

Aşağıdaki örnekte kullanarak TypeFilterAttributebağımsız değişkenlerin bir türe nasıl geçir kullanıldığı gösterilmektedir:

[TypeFilter(typeof(LoggingResponseHeaderFilter),
    Arguments = new object[] { "Filter-Header", "Filter Value" })]
public IActionResult WithTypeFilter() =>
    Content($"- {nameof(FilterDependenciesController)}.{nameof(WithTypeFilter)}");

Yetkilendirme filtreleri

Yetkilendirme filtreleri:

  • İlk filtreler filtre işlem hattında çalıştırılır.
  • Eylem yöntemlerine erişimi denetleme.
  • Önce yöntemine sahip olun, ancak sonra yöntemi yok.

Özel yetkilendirme filtreleri için özel yetkilendirme çerçevesi gerekir. Özel filtre yazmak yerine yetkilendirme ilkelerini yapılandırmayı veya özel yetkilendirme ilkesi yazmayı tercih edin. Yerleşik yetkilendirme filtresi:

  • Yetkilendirme sistemini çağırır.
  • İstekleri yetkilendirmez.

Yetkilendirme filtrelerinde özel durumlar oluşturmayın:

  • Özel durum işlenmez.
  • Özel durum filtreleri özel durumu işlemez.

Yetkilendirme filtresinde bir özel durum oluştuğunda bir sınama vermeyi göz önünde bulundurun.

Yetkilendirme hakkında daha fazla bilgi edinin.

Kaynak filtreleri

Kaynak filtreleri:

Kaynak filtreleri, işlem hattının büyük bölümünü kısa devre yapmak için kullanışlıdır. Örneğin, önbelleğe alma filtresi önbellek isabetinde işlem hattının geri kalanını önleyebilir.

Kaynak filtresi örnekleri:

Eylem filtreleri

Eylem filtreleri Sayfalar'a Razor uygulanmaz. RazorSayfalar ve'i IAsyncPageFilterdesteklerIPageFilter. Daha fazla bilgi için bkz. Sayfalar için Razor filtreleme yöntemleri.

Eylem filtreleri:

Aşağıdaki kodda örnek bir eylem filtresi gösterilmektedir:

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
    }
}

ActionExecutingContext aşağıdaki özellikleri sağlar:

  • ActionArguments - bir eylem yöntemine girişlerin okunmasını sağlar.
  • Controller - denetleyici örneğinin manipülesini etkinleştirir.
  • Result - eylem yönteminin ve sonraki eylem filtrelerinin kısa devre yürütmesini ayarlama Result .

Bir eylem yönteminde özel durum oluşturma:

  • Sonraki filtrelerin çalıştırılmasını engeller.
  • ayarından Resultfarklı olarak, başarılı bir sonuç yerine bir hata olarak değerlendirilir.

ActionExecutedContext ve Result artı olarak aşağıdaki özellikleri sağlarController:

  • Canceled - Eylem yürütmesi başka bir filtre tarafından kısa devreliyse true.
  • Exception - Eylem veya daha önce çalıştırmış bir eylem filtresi özel durum oluşturduysa null olmayan. Bu özellik null olarak ayarlanıyor:
    • Özel durumu etkili bir şekilde işler.
    • Result , eylem yönteminden döndürülür gibi yürütülür.

için IAsyncActionFilteröğesine yönelik bir çağrı:ActionExecutionDelegate

  • Sonraki tüm eylem filtrelerini ve eylem yöntemini yürütür.
  • ActionExecutedContext döndürür.

Kısa devre için, bir sonuç örneğine atayın Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.ResultActionExecutionDelegateve (çağırmayın next ).

Çerçeve, alt sınıflandırılabilir bir soyut ActionFilterAttribute sağlar.

Eylem OnActionExecuting filtresi aşağıdakileri yapmak için kullanılabilir:

  • Model durumunu doğrulayın.
  • Durum geçersizse bir hata döndürür.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }
}

Dekont

Özniteliğiyle [ApiController] açıklama eklenmiş denetleyiciler model durumunu otomatik olarak doğrular ve 400 yanıtı döndürür. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

yöntemi, OnActionExecuted eylem yönteminden sonra çalışır:

  • Ve özelliği aracılığıyla Result eylemin sonuçlarını görebilir ve işleyebilir.
  • Canceled eylem yürütmesi başka bir filtre tarafından kısa devreliyse true olarak ayarlanır.
  • Exception , eylem veya sonraki bir eylem filtresi özel durum oluşturduysa null olmayan bir değere ayarlanır. Null olarak ayarlanıyor Exception :
    • Bir özel durumu etkili bir şekilde işler.
    • ActionExecutedContext.Result , eylem yönteminden normal şekilde döndürülür gibi yürütülür.

Özel durum filtreleri

Özel durum filtreleri:

Aşağıdaki örnek özel durum filtresi, uygulama geliştirme aşamasındayken oluşan özel durumlar hakkındaki ayrıntıları görüntüler:

public class SampleExceptionFilter : IExceptionFilter
{
    private readonly IHostEnvironment _hostEnvironment;

    public SampleExceptionFilter(IHostEnvironment hostEnvironment) =>
        _hostEnvironment = hostEnvironment;

    public void OnException(ExceptionContext context)
    {
        if (!_hostEnvironment.IsDevelopment())
        {
            // Don't display exception details unless running in Development.
            return;
        }

        context.Result = new ContentResult
        {
            Content = context.Exception.ToString()
        };
    }
}

Aşağıdaki kod özel durum filtresini test ediyor:

[TypeFilter(typeof(SampleExceptionFilter))]
public class ExceptionController : Controller
{
    public IActionResult Index() =>
        Content($"- {nameof(ExceptionController)}.{nameof(Index)}");
}

Özel durum filtreleri:

  • Etkinlik öncesi ve sonrası yok.
  • veya OnExceptionAsyncuygulayınOnException.
  • Sayfa veya denetleyici oluşturma, model bağlama, eylem filtreleri veya eylem yöntemlerinde Razor oluşan işlenmeyen özel durumları işleyin.
  • Kaynak filtrelerinde, sonuç filtrelerinde veya MVC sonuç yürütmesinde oluşan özel durumları yakalamayın.

Bir özel durumu işlemek için özelliğini olarak true ayarlayın ExceptionHandled veya özelliğini atayınResult. Bu, özel durumun yayılmasını durdurur. Özel durum filtresi bir özel durumu "başarılı" duruma getiremez. Bunu yalnızca bir eylem filtresi yapabilir.

Özel durum filtreleri:

  • Eylemler içinde oluşan özel durumları yakalamak için iyidir.
  • Hata işleme ara yazılımı kadar esnek değildir.

Özel durum işleme için ara yazılımı tercih edin. Özel durum filtrelerini yalnızca hata işlemenin hangi eylem yönteminin çağrıldığı temelinde farklı olduğu durumlarda kullanın. Örneğin, bir uygulamanın hem API uç noktaları hem de görünümler/HTML için eylem yöntemleri olabilir. API uç noktaları hata bilgilerini ON olarak JSdöndürebilirken, görünüm tabanlı eylemler html olarak bir hata sayfası döndürebilir.

Sonuç filtreleri

Sonuç filtreleri:

IResultFilter ve IAsyncResultFilter

Aşağıdaki kodda örnek bir sonuç filtresi gösterilmektedir:

public class SampleResultFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        // Do something before the result executes.
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Do something after the result executes.
    }
}

Yürütülen sonuç türü eyleme bağlıdır. Görünüm döndüren eylem, yürütülmekte olan ViewResult tüm razor işlemlerini içerir. BIR API yöntemi, sonucun yürütülmesinin bir parçası olarak bazı serileştirmeler gerçekleştirebilir. Eylem sonuçları hakkında daha fazla bilgi edinin.

Sonuç filtreleri yalnızca bir eylem veya eylem filtresi bir eylem sonucu ürettiğinde yürütülür. Sonuç filtreleri şu durumlarda yürütülür:

  • Yetkilendirme filtresi veya kaynak filtresi işlem hattını kısa devrelere bağlar.
  • Özel durum filtresi, bir eylem sonucu oluşturarak özel durumu işler.

yöntemi, Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting olarak ayarlayarak Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel eylem sonucunun ve sonraki sonuç filtrelerinin kısa devre yürütmesini truesağlayabilir. Boş yanıt oluşturmamak için kısa devre yaparken yanıt nesnesine yazın. içinde IResultFilter.OnResultExecutingözel durum oluşturma:

  • Eylem sonucunun ve sonraki filtrelerin yürütülmesini engeller.
  • Başarılı bir sonuç yerine hata olarak değerlendirilir.

Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted Yöntem çalıştırıldığında, yanıt büyük olasılıkla istemciye gönderilmiştir. Yanıt istemciye zaten gönderilmişse değiştirilemez.

ResultExecutedContext.Canceled , eylem sonucu yürütmesinin başka bir filtre tarafından kısa devreli olup olmadığını olarak ayarlanır true .

ResultExecutedContext.Exception , eylem sonucu veya sonraki bir sonuç filtresi özel durum oluşturduysa null olmayan bir değere ayarlanır. null ayarı Exception bir özel durumu etkili bir şekilde işler ve özel durumun işlem hattında daha sonra yeniden oluşmasını önler. Sonuç filtresinde özel durum işlenirken yanıta veri yazmanın güvenilir bir yolu yoktur. Bir eylem sonucu özel durum oluştururken üst bilgiler istemciye boşaltıldıysa, hata kodu göndermek için güvenilir bir mekanizma yoktur.

bir IAsyncResultFilteriçin, üzerindeki ResultExecutionDelegate çağrısı await next sonraki tüm sonuç filtrelerini ve eylem sonucunu yürütür. Kısa devre için olarak ayarlayın ResultExecutingContext.Canceltrue ve çağrısı ResultExecutionDelegateyapmayın:

public class SampleAsyncResultFilter : IAsyncResultFilter
{
    public async Task OnResultExecutionAsync(
        ResultExecutingContext context, ResultExecutionDelegate next)
    {
        if (context.Result is not EmptyResult)
        {
            await next();
        }
        else
        {
            context.Cancel = true;
        }
    }
}

Çerçeve, alt sınıflandırılabilir bir soyut ResultFilterAttribute sağlar. Daha önce gösterilen ResponseHeaderAttribute sınıfı bir sonuç filtresi özniteliği örneğidir.

IAlwaysRunResultFilter ve IAsyncAlwaysRunResultFilter

IAlwaysRunResultFilter ve IAsyncAlwaysRunResultFilter arabirimleri, tüm eylem sonuçları için çalışan bir IResultFilter uygulama bildirir. Bu, tarafından üretilen eylem sonuçlarını içerir:

  • Yetkilendirme filtreleri ve kısa devreli kaynak filtreleri.
  • Özel durum filtreleri.

Örneğin, aşağıdaki filtre her zaman çalışır ve içerik anlaşması başarısız olduğunda 422 İşlenemez Varlık durum koduyla bir eylem sonucu (ObjectResult) ayarlar:

public class UnprocessableResultFilter : IAlwaysRunResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is StatusCodeResult statusCodeResult
            && statusCodeResult.StatusCode == StatusCodes.Status415UnsupportedMediaType)
        {
            context.Result = new ObjectResult("Unprocessable")
            {
                StatusCode = StatusCodes.Status422UnprocessableEntity
            };
        }
    }

    public void OnResultExecuted(ResultExecutedContext context) { }
}

IFilterFactory

IFilterFactory uygular IFilterMetadata. Bu nedenle, bir IFilterFactory örnek filtre işlem hattının herhangi bir IFilterMetadata yerinde örnek olarak kullanılabilir. Çalışma zamanı filtreyi çağırmaya hazırlandığında, bunu bir IFilterFactoryöğesine dönüştürmeye çalışır. Bu atama başarılı olursa, CreateInstance çağrılan örneği oluşturmak IFilterMetadata için yöntemi çağrılır. Bu esnek bir tasarım sağlar, çünkü uygulama başlatıldığında hassas filtre işlem hattının açıkça ayarlanması gerekmez.

IFilterFactory.IsReusable:

  • Fabrika tarafından oluşturulan filtre örneğinin, içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin bir ipucudur.
  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

ASP.NET Core çalışma zamanı aşağıdakileri garanti etmez:

  • Filtrenin tek bir örneğinin oluşturulacağı.
  • Filtre daha sonraki bir noktada DI kapsayıcısından yeniden istenmeyecek.

Uyarı

Yalnızca filtrelerin kaynağı belirsizse, filtreler durum bilgisi yoksa ve filtrelerin birden çok HTTP isteğinde kullanılması güvenliyse döndürülecek true şekilde yapılandırınIFilterFactory.IsReusable. Örneğin, kapsamı belirlenmiş veya döndürürse IFilterFactory.IsReusable geçici olarak kaydedilen DI filtrelerini döndürmeyin true.

IFilterFactory filtre oluşturmaya yönelik başka bir yaklaşım olarak özel öznitelik uygulamaları kullanılarak uygulanabilir:

public class ResponseHeaderFilterFactory : Attribute, IFilterFactory
{
    public bool IsReusable => false;

    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider) =>
        new InternalResponseHeaderFilter();

    private class InternalResponseHeaderFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context) =>
            context.HttpContext.Response.Headers.Add(
                nameof(OnActionExecuting), nameof(InternalResponseHeaderFilter));

        public void OnActionExecuted(ActionExecutedContext context) { }
    }

Filtre aşağıdaki kodda uygulanır:

[ResponseHeaderFilterFactory]
public IActionResult Index() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(Index)}");

Bir öznitelikte uygulanan IFilterFactory

Uygulayan IFilterFactory filtreler, aşağıdaki filtreler için kullanışlıdır:

  • Parametrelerin geçirilmesini gerektirmez.
  • DI tarafından doldurulması gereken oluşturucu bağımlılıkları vardır.

TypeFilterAttribute uygular IFilterFactory. IFilterFactoryCreateInstance örneği oluşturmak IFilterMetadata için yöntemini kullanıma sunar. CreateInstance , belirtilen türü services kapsayıcısından (DI) yükler.

public class SampleActionTypeFilterAttribute : TypeFilterAttribute
{
    public SampleActionTypeFilterAttribute()
         : base(typeof(InternalSampleActionFilter)) { }

    private class InternalSampleActionFilter : IActionFilter
    {
        private readonly ILogger<InternalSampleActionFilter> _logger;

        public InternalSampleActionFilter(ILogger<InternalSampleActionFilter> logger) =>
            _logger = logger;

        public void OnActionExecuting(ActionExecutingContext context)
        {
            _logger.LogInformation(
                $"- {nameof(InternalSampleActionFilter)}.{nameof(OnActionExecuting)}");
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            _logger.LogInformation(
                $"- {nameof(InternalSampleActionFilter)}.{nameof(OnActionExecuted)}");
        }
    }
}

Aşağıdaki kod, filtreyi uygulamak için üç yaklaşım gösterir:

[SampleActionTypeFilter]
public IActionResult WithDirectAttribute() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(WithDirectAttribute)}");

[TypeFilter(typeof(SampleActionTypeFilterAttribute))]
public IActionResult WithTypeFilterAttribute() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(WithTypeFilterAttribute)}");

[ServiceFilter(typeof(SampleActionTypeFilterAttribute))]
public IActionResult WithServiceFilterAttribute() =>
    Content($"- {nameof(FilterFactoryController)}.{nameof(WithServiceFilterAttribute)}");

Yukarıdaki kodda, filtreyi uygulamak için ilk yaklaşım tercih edilir.

Filtre işlem hattında ara yazılım kullanma

Kaynak filtreleri, işlem hattında daha sonra gelen her şeyin yürütülmesini çevreleyen ara yazılım gibi çalışır. Ancak filtreler, çalışma zamanının parçası oldukları için ara yazılımdan farklıdır ve bu da bağlam ve yapılara erişimleri olduğu anlamına gelir.

Ara yazılımı filtre olarak kullanmak için, filtre işlem hattına eklenecek ara yazılımı belirten bir yönteme sahip bir Configure tür oluşturun. Aşağıdaki örnek, yanıt üst bilgisini ayarlamak için ara yazılımı kullanır:

public class FilterMiddlewarePipeline
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            context.Response.Headers.Add("Pipeline", "Middleware");

            await next();
        });
    }
}

Ara yazılımı çalıştırmak için öğesini MiddlewareFilterAttribute kullanın:

[MiddlewareFilter(typeof(FilterMiddlewarePipeline))]
public class FilterMiddlewareController : Controller
{
    public IActionResult Index() =>
        Content($"- {nameof(FilterMiddlewareController)}.{nameof(Index)}");
}

Ara yazılım filtreleri, filtre işlem hattının Kaynak filtreleri ile aynı aşamasında, model bağlamadan önce ve işlem hattının geri kalanından sonra çalışır.

İş parçacığı güvenliği

Filtrenin bir örneğini yerine içine TypeAddgeçirirken, filtre tekildir ve iş parçacığı açısından güvenli değildir.

Ek kaynaklar

Kirk Larkin, Rick Anderson, Tom Dykstra ve Steve Smith tarafından

ASP.NET Core'daki filtreler , istek işleme işlem hattındaki belirli aşamaların öncesinde veya sonrasında kodun çalıştırılmasına izin verir.

Yerleşik filtreler şunlar gibi görevleri işler:

  • Yetkilendirme, kullanıcının yetkilendirilmemiş kaynaklara erişimini engelleme.
  • Yanıt önbelleğe alma, önbelleğe alınmış bir yanıt döndürmek için istek işlem hattını kısa devreden geçirme.

Çapraz kesme sorunlarını çözmek için özel filtreler oluşturulabilir. Çapraz kesme endişelerine örnek olarak hata işleme, önbelleğe alma, yapılandırma, yetkilendirme ve günlüğe kaydetme verilebilir. Filtreler kodun çoğaltılmasını önler. Örneğin, hata işleme özel durum filtresi hata işlemeyi bir araya gelebilir.

Bu belge Sayfalar, API denetleyicileri ve görünümlere sahip denetleyiciler için Razor geçerlidir. Filtreler bileşenlerle Razordoğrudan çalışmaz. Filtre yalnızca şu durumlarda bir bileşeni dolaylı olarak etkileyebilir:

  • Bileşen bir sayfaya veya görünüme eklenir.
  • Sayfa veya denetleyici ve görünüm filtreyi kullanır.

Örneği görüntüleme veya indirme (indirme).

Filtreler nasıl çalışır?

Filtreler, bazen filtre işlem hattı olarak da adlandırılan ASP.NET Core eylem çağırma işlem hattı içinde çalışır. Filtre işlem hattı, ASP.NET Core yürütülecek eylemi seçtikten sonra çalışır.

The request is processed through Other Middleware, Routing Middleware, Action Selection, and the Action Invocation Pipeline. The request processing continues back through Action Selection, Routing Middleware, and various Other Middleware before becoming a response sent to the client.

Filtre türleri

Her filtre türü, filtre işlem hattında farklı bir aşamada yürütülür:

  • Yetkilendirme filtreleri önce çalışır ve kullanıcının istek için yetkilendirilip yetkilendirilmediğini belirlemek için kullanılır. yetkilendirme, istek yetkilendirilmediyse işlem hattının kısa devresini filtreler.

  • Kaynak filtreleri:

    • Yetkilendirmeden sonra çalıştırın.
    • OnResourceExecuting filtre işlem hattının geri kalanından önce kodu çalıştırır. Örneğin, OnResourceExecuting model bağlamadan önce kodu çalıştırır.
    • OnResourceExecuted işlem hattının geri kalanı tamamlandıktan sonra kodu çalıştırır.
  • Eylem filtreleri:

    • Bir eylem yöntemi çağrılmadan hemen önce ve sonra kodu çalıştırın.
    • Bir eyleme geçirilen bağımsız değişkenleri değiştirebilir.
    • Eylemden döndürülen sonucu değiştirebilir.
    • Sayfalar'da Razor desteklenmez.
  • Özel durum filtreleri , yanıt gövdesi yazılmadan önce gerçekleşen işlenmeyen özel durumlara genel ilkeler uygular.

  • Sonuç filtreleri , eylem sonuçlarının yürütülmesinden hemen önce ve sonra kodu çalıştırır. Yalnızca eylem yöntemi başarıyla yürütülürken çalışır. Bunlar, görünüm veya biçimlendirici yürütmesini çevrelemesi gereken mantık için kullanışlıdır.

Aşağıdaki diyagramda filtre türlerinin filtre işlem hattında nasıl etkileşimde olduğu gösterilmektedir.

The request is processed through Authorization Filters, Resource Filters, Model Binding, Action Filters, Action Execution and Action Result Conversion, Exception Filters, Result Filters, and Result Execution. On the way out, the request is only processed by Result Filters and Resource Filters before becoming a response sent to the client.

Uygulama

Filtreler, farklı arabirim tanımları aracılığıyla hem zaman uyumlu hem de zaman uyumsuz uygulamaları destekler.

Zaman uyumlu filtreler, işlem hattı aşamasından önce ve sonra kod çalıştırır. Örneğin, OnActionExecuting eylem yöntemi çağrılmadan önce çağrılır. OnActionExecuted , eylem yöntemi döndürdüğünde çağrılır.

public class MySampleActionFilter : IActionFilter 
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }
}

Yukarıdaki kodda MyDebug, örnek indirmedeki bir yardımcı program işlevidir.

Zaman uyumsuz filtreler bir On-Stage-ExecutionAsync yöntem tanımlar. Örneğin, OnActionExecutionAsync:

public class SampleAsyncActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next)
    {
        // Do something before the action executes.

        // next() calls the action method.
        var resultContext = await next();
        // resultContext.Result is set.
        // Do something after the action executes.
    }
}

Yukarıdaki kodda SampleAsyncActionFilter , eylem yöntemini yürüten bir ActionExecutionDelegate (next) vardır.

Birden çok filtre aşaması

Birden çok filtre aşaması için arabirimler tek bir sınıfta uygulanabilir. Örneğin, ActionFilterAttribute sınıfı şunları uygular:

Her ikisini birden değil, bir filtre arabiriminin zaman uyumlu veya zaman uyumsuz sürümünü uygulayın. Çalışma zamanı ö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. Hem zaman uyumsuz hem de zaman uyumlu arabirimler bir sınıfta uygulanırsa, yalnızca zaman uyumsuz yöntem çağrılır. gibi ActionFilterAttributesoyut sınıfları kullanırken, her filtre türü için yalnızca zaman uyumlu yöntemleri veya zaman uyumsuz yöntemleri geçersiz kılın.

Yerleşik filtre öznitelikleri

ASP.NET Core, alt sınıfa alınabilen ve özelleştirilebilen yerleşik öznitelik tabanlı filtreler içerir. Örneğin, aşağıdaki sonuç filtresi yanıta bir üst bilgi ekler:

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 });
        base.OnResultExecuting(context);
    }
}

Öznitelikler, önceki örnekte gösterildiği gibi filtrelerin bağımsız değişkenleri kabul etmelerine izin verir. öğesini AddHeaderAttribute bir denetleyiciye veya eylem yöntemine uygulayın ve HTTP üst bilgisinin adını ve değerini belirtin:

[AddHeader("Author", "Rick Anderson")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

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

Aşağıdaki kod aşağıdakileri ActionFilterAttribute uygular:

  • Yapılandırma sisteminden başlığı ve adı okur. Önceki örnekten farklı olarak aşağıdaki kod, koda filtre parametrelerinin eklenmesini gerektirmez.
  • Başlık ve adı yanıt üst bilgisine ekler.
public class MyActionFilterAttribute : ActionFilterAttribute
{
    private readonly PositionOptions _settings;

    public MyActionFilterAttribute(IOptions<PositionOptions> options)
    {
        _settings = options.Value;
        Order = 1;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Response.Headers.Add(_settings.Title, 
                                                 new string[] { _settings.Name });
        base.OnResultExecuting(context);
    }
}

Yapılandırma seçenekleri, seçenekler deseni kullanılarak yapılandırma sistemindensağlanır. Örneğin, dosyasından appsettings.json :

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

StartUp.ConfigureServicesiçinde:

  • PositionOptions sınıfı, yapılandırma alanıyla hizmet kapsayıcısına "Position" eklenir.
  • MyActionFilterAttribute, hizmet kapsayıcısına eklenir.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(
             Configuration.GetSection("Position"));
    services.AddScoped<MyActionFilterAttribute>();

    services.AddControllersWithViews();
}

Aşağıdaki kod sınıfını PositionOptions gösterir:

public class PositionOptions
{
    public string Title { get; set; }
    public string Name { get; set; }
}

Aşağıdaki kod yöntemine Index2 uygularMyActionFilterAttribute:

[AddHeader("Author", "Rick Anderson")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

    [ServiceFilter(typeof(MyActionFilterAttribute))]
    public IActionResult Index2()
    {
        return Content("Header values by configuration.");
    }

Yanıt Üst Bilgileri altında, author: Rick AndersonEditor: Joe Smith ve uç nokta çağrıldığında Sample/Index2 görüntülenir.

Aşağıdaki kod ve AddHeaderAttribute öğesini Sayfaya Razor uygularMyActionFilterAttribute:

[AddHeader("Author", "Rick Anderson")]
[ServiceFilter(typeof(MyActionFilterAttribute))]
public class IndexModel : PageModel
{
    public void OnGet()
    {
    }
}

Filtreler Sayfa işleyici yöntemlerine Razor uygulanamaz. Bunlar Sayfa modeline Razor veya genel olarak uygulanabilir.

Filtre arabirimlerinin birkaçı, özel uygulamalar için temel sınıflar olarak kullanılabilecek ilgili özniteliklere sahiptir.

Filtre öznitelikleri:

Filtre kapsamları ve yürütme sırası

İşlem hattına üç kapsamdan birine filtre eklenebilir:

  • Denetleyici eyleminde öznitelik kullanma. Filtre öznitelikleri Sayfalar işleyici yöntemlerine Razor uygulanamaz.
  • Denetleyicide veya Razor Sayfada bir öznitelik kullanma.
  • Aşağıdaki kodda gösterildiği gibi tüm denetleyiciler, eylemler ve Razor Sayfalar için genel olarak:
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
   {
        options.Filters.Add(typeof(MySampleActionFilter));
    });
}

Varsayılan yürütme sırası

İşlem hattının belirli bir aşaması için birden çok filtre olduğunda kapsam varsayılan filtre yürütme sırasını belirler. Genel filtreler sınıf filtrelerini çevreler ve bu da yöntem filtrelerini çevreler.

Filtre iç içe yerleştirmenin bir sonucu olarak, filtrelerden sonraki kod, önceki kodun ters sırasına göre çalışır. Filtre sırası:

  • Genel filtrelerin önceki kodu.
    • Denetleyicinin ve Razor Sayfa filtrelerinin önceki kodu.
      • Önceki eylem yöntemi kodu filtreler.
      • Eylemden sonraki kod yöntemi filtreler.
    • Denetleyicinin ve Razor Sayfa filtrelerinin son kodu.
  • Genel filtrelerin after kodu.

Zaman uyumlu eylem filtreleri için filtre yöntemlerinin çağrılma sırasını gösteren aşağıdaki örnek.

Sequence Filtre kapsamı Filter yöntemi
Kategori 1 Global OnActionExecuting
2 Denetleyici veya Razor Sayfa OnActionExecuting
3 Yöntem OnActionExecuting
4 Yöntem OnActionExecuted
5 Denetleyici veya Razor Sayfa OnActionExecuted
6 Global OnActionExecuted

Denetleyici düzeyi filtreleri

Temel sınıftan Controller devralan her denetleyici , Controller.OnActionExecutionAsyncve Controller.OnActionExecutedOnActionExecuted yöntemlerini içerirController.OnActionExecuting. Bu yöntemler:

  • Belirli bir eylem için çalışan filtreleri sarmalayın.
  • OnActionExecuting , eylemin filtrelerinden önce çağrılır.
  • OnActionExecuted tüm eylem filtrelerinden sonra çağrılır.
  • OnActionExecutionAsync , eylemin filtrelerinden önce çağrılır. Eylem yönteminden sonra çalıştırıldıktan sonra next filtredeki kod.

Örneğin, indirme örneğinde başlangıçta MySampleActionFilter genel olarak uygulanır.

:TestController

  • eylemine SampleActionFilterAttributeFilterTest2 ([SampleActionFilter]) uygular.
  • ve OnActionExecutedgeçersiz kılmalarıOnActionExecuting.
public class TestController : Controller
{
    [SampleActionFilter(Order = int.MinValue)]
    public IActionResult FilterTest2()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuted(context);
    }
}

MyDisplayRouteInfo, Rick.Docs.Samples.RouteInfo NuGet paketi tarafından sağlanır ve yol bilgilerini görüntüler.

Gezinmek için https://localhost:5001/Test/FilterTest2 aşağıdaki kodu çalıştırın:

  • TestController.OnActionExecuting
    • MySampleActionFilter.OnActionExecuting
      • SampleActionFilterAttribute.OnActionExecuting
        • TestController.FilterTest2
      • SampleActionFilterAttribute.OnActionExecuted
    • MySampleActionFilter.OnActionExecuted
  • TestController.OnActionExecuted

Denetleyici düzeyi filtreleri Order özelliğini olarak int.MinValueayarlar. Denetleyici düzeyi filtreleri , yöntemlere filtre uygulandıktan sonra çalışacak şekilde ayarlanamaz . Sipariş, sonraki bölümde açıklanmıştır.

Sayfalar için Razor bkz. Filtre yöntemlerini geçersiz kılarak Sayfa filtrelerini uygulamaRazor.

Varsayılan sırayı geçersiz kılma

varsayılan yürütme dizisi uygulanarak IOrderedFiltergeçersiz kılınabilir. IOrderedFilterOrder yürütme sırasını belirlemek için kapsam üzerinde öncelikli olan özelliğini kullanıma sunar. Daha düşük Order değere sahip bir filtre:

  • daha yüksek değere Ordersahip bir filtrenin önceki kodunu çalıştırır.
  • Daha yüksek Order bir değere sahip bir filtreden sonraki kodu çalıştırır.

Order özelliği bir oluşturucu parametresiyle ayarlanır:

[SampleActionFilter(Order = int.MinValue)]

Aşağıdaki denetleyicideki iki eylem filtresini göz önünde bulundurun:

[MyAction2Filter]
public class Test2Controller : Controller
{
    public IActionResult FilterTest2()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuted(context);
    }
}

içinde StartUp.ConfigureServicesgenel bir filtre eklenir:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
   {
        options.Filters.Add(typeof(MySampleActionFilter));
    });
}

3 filtresi aşağıdaki sırayla çalışır:

  • Test2Controller.OnActionExecuting
    • MySampleActionFilter.OnActionExecuting
      • MyAction2FilterAttribute.OnActionExecuting
        • Test2Controller.FilterTest2
      • MyAction2FilterAttribute.OnResultExecuting
    • MySampleActionFilter.OnActionExecuted
  • Test2Controller.OnActionExecuted

özelliği, Order filtrelerin çalıştırıldığı sırayı belirlerken kapsamı geçersiz kılar. Filtreler önce düzene göre sıralanır, ardından bağlam, bağlarını kesmek için kullanılır. Tüm yerleşik filtreler uygular IOrderedFilter ve varsayılan Order değeri 0 olarak ayarlar. Daha önce belirtildiği gibi, denetleyici düzeyi filtreleri Order özelliğini int.MinValue Yerleşik filtreler için olarak ayarlar, kapsam sıfır olmayan bir değere ayarlanmadığı sürece Order sırayı belirler.

Yukarıdaki kodda, MySampleActionFilter denetleyici kapsamına sahip olan öncesinde MyAction2FilterAttributeçalışması için genel kapsama sahiptir. İlk çalıştırmayı yapmak MyAction2FilterAttribute için sırasını olarak int.MinValueayarlayın:

[MyAction2Filter(int.MinValue)]
public class Test2Controller : Controller
{
    public IActionResult FilterTest2()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), HttpContext.Request.Path);
        base.OnActionExecuted(context);
    }
}

Önce genel filtrenin MySampleActionFilter çalıştırılmasını sağlamak için int.MinValueolarak ayarlayınOrder:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
   {
        options.Filters.Add(typeof(MySampleActionFilter),
                            int.MinValue);
    });
}

İptal ve kısa devre

Filtre işlem hattı, filtre yöntemine Result sağlanan parametrede ResourceExecutingContext özelliği ayarlanarak kısa devre yapılabilir. Örneğin, aşağıdaki Kaynak filtresi işlem hattının geri kalanının yürütülmesini engeller:

public class ShortCircuitingResourceFilterAttribute : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        context.Result = new ContentResult()
        {
            Content = "Resource unavailable - header not set."
        };
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
    }
}

Aşağıdaki kodda, hem hem de ShortCircuitingResourceFilterAddHeader filtresi eylem yöntemini hedefler SomeResource . :ShortCircuitingResourceFilter

  • Önce çalışır çünkü bu bir Kaynak Filtresi ve AddHeader bir Eylem Filtresidir.
  • İşlem hattının geri kalanını kısa devreler.

Bu nedenle AddHeader , filtre hiçbir zaman eylem için SomeResource çalıştırılır. Bu davranış, her iki filtre de önce çalıştırılan ShortCircuitingResourceFilter eylem yöntemi düzeyinde uygulanmışsa aynı olacaktır. önce ShortCircuitingResourceFilter filtre türü nedeniyle veya özelliğin açık kullanımıyla Order çalıştırılır.

[AddHeader("Author", "Rick Anderson")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

    [ServiceFilter(typeof(MyActionFilterAttribute))]
    public IActionResult Index2()
    {
        return Content("Header values by configuration.");
    }

    [ShortCircuitingResourceFilter]
    public IActionResult SomeResource()
    {
        return Content("Successful access to resource - header is set.");
    }

    [AddHeaderWithFactory]
    public IActionResult HeaderWithFactory()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }
}

Bağımlılık ekleme

Filtreler türe veya örneğe göre eklenebilir. Bir örnek eklenirse, bu örnek her istek için kullanılır. Bir tür eklenirse, tür etkinleştirilir. Tür etkinleştirilmiş filtre şu anlama gelir:

  • Her istek için bir örnek oluşturulur.
  • Tüm oluşturucu bağımlılıkları bağımlılık ekleme (DI) ile doldurulur.

Öznitelik olarak uygulanan ve doğrudan denetleyici sınıflarına veya eylem yöntemlerine eklenen filtrelerin bağımlılık ekleme (DI) tarafından sağlanan oluşturucu bağımlılıkları olamaz. Oluşturucu bağımlılıkları DI tarafından sağlanamıyor çünkü:

  • Özniteliklerin uygulandığı yerde oluşturucu parametreleri sağlanmalıdır.
  • Bu, özniteliklerin çalışma şekliyle ilgili bir sınırlamadır.

Aşağıdaki filtreler DI'den sağlanan oluşturucu bağımlılıklarını destekler:

Yukarıdaki filtreler bir denetleyiciye veya eylem yöntemine uygulanabilir:

Günlükçüler DI'den kullanılabilir. Ancak, filtreleri yalnızca günlüğe kaydetme amacıyla oluşturmaktan ve kullanmaktan kaçının. Yerleşik çerçeve günlüğü genellikle günlüğe kaydetme için gerekenleri sağlar. Filtrelere eklenen günlüğe kaydetme:

  • İş etki alanı endişelerine veya filtreye özgü davranışlara odaklanmalıdır.
  • Eylemleri veya diğer çerçeve olaylarını günlüğe kaydetmemelidir. Yerleşik filtreler, eylemleri ve çerçeve olaylarını günlüğe kaydeder.

ServiceFilterAttribute

Hizmet filtresi uygulama türleri içinde ConfigureServiceskaydedilir. A ServiceFilterAttribute , DI'den filtrenin bir örneğini alır.

Aşağıdaki kod şunları AddHeaderResultServiceFiltergösterir:

public class AddHeaderResultServiceFilter : IResultFilter
{
    private ILogger _logger;
    public AddHeaderResultServiceFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<AddHeaderResultServiceFilter>();
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add(
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation("Header added: {HeaderName}", headerName);
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Can't add to headers here because response has started.
        _logger.LogInformation("AddHeaderResultServiceFilter.OnResultExecuted");
    }
}

Aşağıdaki kodda DI AddHeaderResultServiceFilter kapsayıcısına eklenir:

public void ConfigureServices(IServiceCollection services)
{
    // Add service filters.
    services.AddScoped<AddHeaderResultServiceFilter>();
    services.AddScoped<SampleActionFilterAttribute>();

    services.AddControllersWithViews(options =>
   {
       options.Filters.Add(new AddHeaderAttribute("GlobalAddHeader",
           "Result filter added to MvcOptions.Filters"));         // An instance
        options.Filters.Add(typeof(MySampleActionFilter));         // By type
        options.Filters.Add(new SampleGlobalActionFilter());       // An instance
    });
}

Aşağıdaki kodda ServiceFilter özniteliği, DI'den filtrenin AddHeaderResultServiceFilter bir örneğini alır:

[ServiceFilter(typeof(AddHeaderResultServiceFilter))]
public IActionResult Index()
{
    return View();
}

kullanırken ServiceFilterAttributeayarı ServiceFilterAttribute.IsReusable:

  • Filtre örneğinin , içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin bir ipucu sağlar. ASP.NET Core çalışma zamanı aşağıdakileri garanti etmez:

    • Filtrenin tek bir örneğinin oluşturulacağı.
    • Filtre daha sonraki bir noktada DI kapsayıcısından yeniden istenmeyecek.
  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

ServiceFilterAttribute uygular IFilterFactory. IFilterFactoryCreateInstance örneği oluşturmak IFilterMetadata için yöntemini kullanıma sunar. CreateInstance belirtilen türü DI'den yükler.

TypeFilterAttribute

TypeFilterAttribute ile benzerdir ServiceFilterAttribute, ancak türü doğrudan DI kapsayıcısından çözümlenmez. kullanarak türün örneğini oluşturur Microsoft.Extensions.DependencyInjection.ObjectFactory.

Türler TypeFilterAttribute doğrudan DI kapsayıcısından çözümlenmediğinden:

  • kullanılarak TypeFilterAttribute başvurulan türlerin DI kapsayıcısına kaydedilmesi gerekmez. Di kapsayıcısı tarafından karşılanan bağımlılıkları vardır.
  • TypeFilterAttribute isteğe bağlı olarak tür için oluşturucu bağımsız değişkenlerini kabul edebilir.

kullanırken TypeFilterAttributeayarı TypeFilterAttribute.IsReusable:

  • Filtre örneğinin , içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin ipucu sağlar. ASP.NET Core çalışma zamanı, filtrenin tek bir örneğinin oluşturulacağını garanti eder.

  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

Aşağıdaki örnekte kullanarak TypeFilterAttributebağımsız değişkenlerin bir türe nasıl geçir kullanıldığı gösterilmektedir:

[TypeFilter(typeof(LogConstantFilter),
    Arguments = new object[] { "Method 'Hi' called" })]
public IActionResult Hi(string name)
{
    return Content($"Hi {name}");
}

Yetkilendirme filtreleri

Yetkilendirme filtreleri:

  • İlk filtreler filtre işlem hattında çalıştırılır.
  • Eylem yöntemlerine erişimi denetleme.
  • Önce yöntemine sahip olun, ancak sonra yöntemi yok.

Özel yetkilendirme filtreleri için özel yetkilendirme çerçevesi gerekir. Özel filtre yazmak yerine yetkilendirme ilkelerini yapılandırmayı veya özel yetkilendirme ilkesi yazmayı tercih edin. Yerleşik yetkilendirme filtresi:

  • Yetkilendirme sistemini çağırır.
  • İstekleri yetkilendirmez.

Yetkilendirme filtrelerinde özel durumlar oluşturmayın:

  • Özel durum işlenmez.
  • Özel durum filtreleri özel durumu işlemez.

Yetkilendirme filtresinde bir özel durum oluştuğunda bir sınama vermeyi göz önünde bulundurun.

Yetkilendirme hakkında daha fazla bilgi edinin.

Kaynak filtreleri

Kaynak filtreleri:

Kaynak filtreleri, işlem hattının büyük bölümünü kısa devre yapmak için kullanışlıdır. Örneğin, önbelleğe alma filtresi önbellek isabetinde işlem hattının geri kalanını önleyebilir.

Kaynak filtresi örnekleri:

Eylem filtreleri

Eylem filtreleri Sayfalar'a Razor uygulanmaz. RazorSayfalar ve'i IAsyncPageFilterdesteklerIPageFilter. Daha fazla bilgi için bkz. Sayfalar için Razor filtreleme yöntemleri.

Eylem filtreleri:

Aşağıdaki kodda örnek bir eylem filtresi gösterilmektedir:

public class MySampleActionFilter : IActionFilter 
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Do something before the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Do something after the action executes.
        MyDebug.Write(MethodBase.GetCurrentMethod(), context.HttpContext.Request.Path);
    }
}

ActionExecutingContext aşağıdaki özellikleri sağlar:

  • ActionArguments - bir eylem yöntemine girişlerin okunmasını sağlar.
  • Controller - denetleyici örneğinin manipülesini etkinleştirir.
  • Result - eylem yönteminin ve sonraki eylem filtrelerinin kısa devre yürütmesini ayarlama Result .

Bir eylem yönteminde özel durum oluşturma:

  • Sonraki filtrelerin çalıştırılmasını engeller.
  • ayarından Resultfarklı olarak, başarılı bir sonuç yerine bir hata olarak değerlendirilir.

ActionExecutedContext ve Result artı olarak aşağıdaki özellikleri sağlarController:

  • Canceled - Eylem yürütmesi başka bir filtre tarafından kısa devreliyse true.

  • Exception - Eylem veya daha önce çalıştırmış bir eylem filtresi özel durum oluşturduysa null olmayan. Bu özellik null olarak ayarlanıyor:

    • Özel durumu etkili bir şekilde işler.
    • Result , eylem yönteminden döndürülür gibi yürütülür.

için IAsyncActionFilteröğesine yönelik bir çağrı:ActionExecutionDelegate

  • Sonraki tüm eylem filtrelerini ve eylem yöntemini yürütür.
  • ActionExecutedContext döndürür.

Kısa devre için, bir sonuç örneğine atayın Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext.ResultActionExecutionDelegateve (çağırmayın next ).

Çerçeve, alt sınıflandırılabilir bir soyut ActionFilterAttribute sağlar.

Eylem OnActionExecuting filtresi aşağıdakileri yapmak için kullanılabilir:

  • Model durumunu doğrulayın.
  • Durum geçersizse bir hata döndürür.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext 
                                           context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(
                                                context.ModelState);
        }
    }

Dekont

Özniteliğiyle [ApiController] açıklama eklenmiş denetleyiciler model durumunu otomatik olarak doğrular ve 400 yanıtı döndürür. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları. yöntemi, OnActionExecuted eylem yönteminden sonra çalışır:

  • Ve özelliği aracılığıyla Result eylemin sonuçlarını görebilir ve işleyebilir.

  • Canceled eylem yürütmesi başka bir filtre tarafından kısa devreliyse true olarak ayarlanır.

  • Exception , eylem veya sonraki bir eylem filtresi özel durum oluşturduysa null olmayan bir değere ayarlanır. Null olarak ayarlanıyor Exception :

    • Bir özel durumu etkili bir şekilde işler.
    • ActionExecutedContext.Result , eylem yönteminden normal şekilde döndürülür gibi yürütülür.
public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext 
                                           context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(
                                                context.ModelState);
        }
    }


    public override void OnActionExecuted(ActionExecutedContext 
                                          context)
    {
        var result = context.Result;
        // Do something with Result.
        if (context.Canceled == true)
        {
            // Action execution was short-circuited by another filter.
        }

        if(context.Exception != null)
        {
            // Exception thrown by action or action filter.
            // Set to null to handle the exception.
            context.Exception = null;
        }
        base.OnActionExecuted(context);
    }
}

Özel durum filtreleri

Özel durum filtreleri:

Aşağıdaki örnek özel durum filtresi, uygulama geliştirme aşamasındayken oluşan özel durumlar hakkındaki ayrıntıları görüntülemek için özel bir hata görünümü kullanır:

public class CustomExceptionFilter : IExceptionFilter
{
    private readonly IWebHostEnvironment _hostingEnvironment;
    private readonly IModelMetadataProvider _modelMetadataProvider;

    public CustomExceptionFilter(
        IWebHostEnvironment hostingEnvironment,
        IModelMetadataProvider modelMetadataProvider)
    {
        _hostingEnvironment = hostingEnvironment;
        _modelMetadataProvider = modelMetadataProvider;
    }

    public void OnException(ExceptionContext context)
    {
        if (!_hostingEnvironment.IsDevelopment())
        {
            return;
        }
        var result = new ViewResult {ViewName = "CustomError"};
        result.ViewData = new ViewDataDictionary(_modelMetadataProvider,
                                                    context.ModelState);
        result.ViewData.Add("Exception", context.Exception);
        // TODO: Pass additional detailed data via ViewData
        context.Result = result;
    }
}

Aşağıdaki kod özel durum filtresini test ediyor:

[TypeFilter(typeof(CustomExceptionFilter))]
public class FailingController : Controller
{
    [AddHeader("Failing Controller", 
               "Won't appear when exception is handled")]
    public IActionResult Index()
    {
        throw new Exception("Testing custom exception filter.");
    }
}

Özel durum filtreleri:

  • Etkinlik öncesi ve sonrası yok.
  • veya OnExceptionAsyncuygulayınOnException.
  • Sayfa veya denetleyici oluşturma, model bağlama, eylem filtreleri veya eylem yöntemlerinde Razor oluşan işlenmeyen özel durumları işleyin.
  • Kaynak filtrelerinde, sonuç filtrelerinde veya MVC sonuç yürütmesinde oluşan özel durumları yakalamayın.

Bir özel durumu işlemek için özelliğini olarak true ayarlayın ExceptionHandled veya özelliğini atayınResult. Bu, özel durumun yayılmasını durdurur. Özel durum filtresi bir özel durumu "başarılı" duruma getiremez. Bunu yalnızca bir eylem filtresi yapabilir.

Özel durum filtreleri:

  • Eylemler içinde oluşan özel durumları yakalamak için iyidir.
  • Hata işleme ara yazılımı kadar esnek değildir.

Özel durum işleme için ara yazılımı tercih edin. Özel durum filtrelerini yalnızca hata işlemenin hangi eylem yönteminin çağrıldığı temelinde farklı olduğu durumlarda kullanın. Örneğin, bir uygulamanın hem API uç noktaları hem de görünümler/HTML için eylem yöntemleri olabilir. API uç noktaları hata bilgilerini ON olarak JSdöndürebilirken, görünüm tabanlı eylemler html olarak bir hata sayfası döndürebilir.

Sonuç filtreleri

Sonuç filtreleri:

IResultFilter ve IAsyncResultFilter

Aşağıdaki kodda HTTP üst bilgisi ekleyen bir sonuç filtresi gösterilmektedir:

public class AddHeaderResultServiceFilter : IResultFilter
{
    private ILogger _logger;
    public AddHeaderResultServiceFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<AddHeaderResultServiceFilter>();
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add(
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation("Header added: {HeaderName}", headerName);
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        // Can't add to headers here because response has started.
        _logger.LogInformation("AddHeaderResultServiceFilter.OnResultExecuted");
    }
}

Yürütülen sonuç türü eyleme bağlıdır. Görünüm döndüren eylem, yürütülmekte olan ViewResult tüm razor işlemlerini içerir. BIR API yöntemi, sonucun yürütülmesinin bir parçası olarak bazı serileştirmeler gerçekleştirebilir. Eylem sonuçları hakkında daha fazla bilgi edinin.

Sonuç filtreleri yalnızca bir eylem veya eylem filtresi bir eylem sonucu ürettiğinde yürütülür. Sonuç filtreleri şu durumlarda yürütülür:

  • Yetkilendirme filtresi veya kaynak filtresi işlem hattını kısa devrelere bağlar.
  • Özel durum filtresi, bir eylem sonucu oluşturarak özel durumu işler.

yöntemi, Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuting olarak ayarlayarak Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext.Cancel eylem sonucunun ve sonraki sonuç filtrelerinin kısa devre yürütmesini truesağlayabilir. Boş yanıt oluşturmamak için kısa devre yaparken yanıt nesnesine yazın. içinde IResultFilter.OnResultExecutingözel durum oluşturma:

  • Eylem sonucunun ve sonraki filtrelerin yürütülmesini engeller.
  • Başarılı bir sonuç yerine hata olarak değerlendirilir.

Microsoft.AspNetCore.Mvc.Filters.IResultFilter.OnResultExecuted Yöntem çalıştırıldığında, yanıt büyük olasılıkla istemciye gönderilmiştir. Yanıt istemciye zaten gönderilmişse değiştirilemez.

ResultExecutedContext.Canceled , eylem sonucu yürütmesinin başka bir filtre tarafından kısa devreli olup olmadığını olarak ayarlanır true .

ResultExecutedContext.Exception , eylem sonucu veya sonraki bir sonuç filtresi özel durum oluşturduysa null olmayan bir değere ayarlanır. null ayarı Exception bir özel durumu etkili bir şekilde işler ve özel durumun işlem hattında daha sonra yeniden oluşmasını önler. Sonuç filtresinde özel durum işlenirken yanıta veri yazmanın güvenilir bir yolu yoktur. Bir eylem sonucu özel durum oluştururken üst bilgiler istemciye boşaltıldıysa, hata kodu göndermek için güvenilir bir mekanizma yoktur.

bir IAsyncResultFilteriçin, üzerindeki ResultExecutionDelegate çağrısı await next sonraki tüm sonuç filtrelerini ve eylem sonucunu yürütür. Kısa devre için olarak ayarlayın ResultExecutingContext.Canceltrue ve çağrısı ResultExecutionDelegateyapmayın:

public class MyAsyncResponseFilter : IAsyncResultFilter
{
    public async Task OnResultExecutionAsync(ResultExecutingContext context,
                                             ResultExecutionDelegate next)
    {
        if (!(context.Result is EmptyResult))
        {
            await next();
        }
        else
        {
            context.Cancel = true;
        }

    }
}

Çerçeve, alt sınıflandırılabilir bir soyut ResultFilterAttribute sağlar. Daha önce gösterilen AddHeaderAttribute sınıfı bir sonuç filtresi özniteliği örneğidir.

IAlwaysRunResultFilter ve IAsyncAlwaysRunResultFilter

IAlwaysRunResultFilter ve IAsyncAlwaysRunResultFilter arabirimleri, tüm eylem sonuçları için çalışan bir IResultFilter uygulama bildirir. Bu, tarafından üretilen eylem sonuçlarını içerir:

  • Yetkilendirme filtreleri ve kısa devreli kaynak filtreleri.
  • Özel durum filtreleri.

Örneğin, aşağıdaki filtre her zaman çalışır ve içerik anlaşması başarısız olduğunda 422 İşlenemez Varlık durum koduyla bir eylem sonucu (ObjectResult) ayarlar:

public class UnprocessableResultFilter : Attribute, IAlwaysRunResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is StatusCodeResult statusCodeResult &&
            statusCodeResult.StatusCode == (int) HttpStatusCode.UnsupportedMediaType)
        {
            context.Result = new ObjectResult("Can't process this!")
            {
                StatusCode = (int) HttpStatusCode.UnsupportedMediaType,
            };
        }
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
    }
}

IFilterFactory

IFilterFactory uygular IFilterMetadata. Bu nedenle, bir IFilterFactory örnek filtre işlem hattının herhangi bir IFilterMetadata yerinde örnek olarak kullanılabilir. Çalışma zamanı filtreyi çağırmaya hazırlandığında, bunu bir IFilterFactoryöğesine dönüştürmeye çalışır. Bu atama başarılı olursa, CreateInstance çağrılan örneği oluşturmak IFilterMetadata için yöntemi çağrılır. Bu esnek bir tasarım sağlar, çünkü uygulama başlatıldığında hassas filtre işlem hattının açıkça ayarlanması gerekmez.

IFilterFactory.IsReusable:

  • Fabrika tarafından oluşturulan filtre örneğinin, içinde oluşturulduğu istek kapsamının dışında yeniden kullanılabilmesine ilişkin bir ipucudur.
  • Tekil dışında bir ömrü olan hizmetlere bağlı bir filtre ile kullanılmamalıdır.

ASP.NET Core çalışma zamanı aşağıdakileri garanti etmez:

  • Filtrenin tek bir örneğinin oluşturulacağı.
  • Filtre daha sonraki bir noktada DI kapsayıcısından yeniden istenmeyecek.

Uyarı

Yalnızca filtrelerin kaynağı belirsizse, filtreler durum bilgisi yoksa ve filtrelerin birden çok HTTP isteğinde kullanılması güvenliyse döndürülecek true şekilde yapılandırınIFilterFactory.IsReusable. Örneğin, kapsamı belirlenmiş veya döndürürse IFilterFactory.IsReusable geçici olarak kaydedilen DI filtrelerini döndürmeyin true. IFilterFactory filtre oluşturmaya yönelik başka bir yaklaşım olarak özel öznitelik uygulamaları kullanılarak uygulanabilir:

public class AddHeaderWithFactoryAttribute : Attribute, IFilterFactory
{
    // Implement IFilterFactory
    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        return new InternalAddHeaderFilter();
    }

    private class InternalAddHeaderFilter : IResultFilter
    {
        public void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Response.Headers.Add(
                "Internal", new string[] { "My header" });
        }

        public void OnResultExecuted(ResultExecutedContext context)
        {
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

Filtre aşağıdaki kodda uygulanır:

[AddHeader("Author", "Rick Anderson")]
public class SampleController : Controller
{
    public IActionResult Index()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }

    [ServiceFilter(typeof(MyActionFilterAttribute))]
    public IActionResult Index2()
    {
        return Content("Header values by configuration.");
    }

    [ShortCircuitingResourceFilter]
    public IActionResult SomeResource()
    {
        return Content("Successful access to resource - header is set.");
    }

    [AddHeaderWithFactory]
    public IActionResult HeaderWithFactory()
    {
        return Content("Examine the headers using the F12 developer tools.");
    }
}

İndirme örneğini çalıştırarak önceki kodu test edin:

  • F12 geliştirici araçlarını çağırın.
  • Şuraya gidin: https://localhost:5001/Sample/HeaderWithFactory

F12 geliştirici araçları, örnek kod tarafından eklenen aşağıdaki yanıt üst bilgilerini görüntüler:

  • author (yazar)Rick Anderson:
  • globaladdheader:Result filter added to MvcOptions.Filters
  • Iç:My header

Yukarıdaki kod iç:My header yanıt üst bilgisini oluşturur.

Bir öznitelikte uygulanan IFilterFactory

Uygulayan IFilterFactory filtreler, aşağıdaki filtreler için kullanışlıdır:

  • Parametrelerin geçirilmesini gerektirmez.
  • DI tarafından doldurulması gereken oluşturucu bağımlılıkları vardır.

TypeFilterAttribute uygular IFilterFactory. IFilterFactoryCreateInstance örneği oluşturmak IFilterMetadata için yöntemini kullanıma sunar. CreateInstance , belirtilen türü services kapsayıcısından (DI) yükler.

public class SampleActionFilterAttribute : TypeFilterAttribute
{
    public SampleActionFilterAttribute()
                         :base(typeof(SampleActionFilterImpl))
    { 
    }

    private class SampleActionFilterImpl : IActionFilter
    {
        private readonly ILogger _logger;
        public SampleActionFilterImpl(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<SampleActionFilterAttribute>();
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
           _logger.LogInformation("SampleActionFilterAttribute.OnActionExecuting");
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            _logger.LogInformation("SampleActionFilterAttribute.OnActionExecuted");
        }
    }
}

Aşağıdaki kod, uygulamasını uygulamak [SampleActionFilter]için üç yaklaşım gösterir:

[SampleActionFilter]
public IActionResult FilterTest()
{
    return Content("From FilterTest");
}

[TypeFilter(typeof(SampleActionFilterAttribute))]
public IActionResult TypeFilterTest()
{
    return Content("From TypeFilterTest");
}

// ServiceFilter must be registered in ConfigureServices or
// System.InvalidOperationException: No service for type '<filter>'
// has been registered. Is thrown.
[ServiceFilter(typeof(SampleActionFilterAttribute))]
public IActionResult ServiceFilterTest()
{
    return Content("From ServiceFilterTest");
}

Yukarıdaki kodda yöntemini ile [SampleActionFilter] süslemek, uygulamasını uygulamak SampleActionFilteriçin tercih edilen yaklaşımdır.

Filtre işlem hattında ara yazılım kullanma

Kaynak filtreleri, işlem hattında daha sonra gelen her şeyin yürütülmesini çevreleyen ara yazılım gibi çalışır. Ancak filtreler, çalışma zamanının parçası oldukları için ara yazılımdan farklıdır ve bu da bağlam ve yapılara erişimleri olduğu anlamına gelir.

Ara yazılımı filtre olarak kullanmak için, filtre işlem hattına eklenecek ara yazılımı belirten bir yönteme sahip bir Configure tür oluşturun. Aşağıdaki örnek, bir istek için geçerli kültürü oluşturmak üzere yerelleştirme ara yazılımını kullanır:

public class LocalizationPipeline
{
    public void Configure(IApplicationBuilder applicationBuilder)
    {
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"),
            new CultureInfo("fr")
        };

        var options = new RequestLocalizationOptions
        {
            DefaultRequestCulture = new RequestCulture(
                                       culture: "en-US", 
                                       uiCulture: "en-US"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures
        };
        options.RequestCultureProviders = new[] 
            { new RouteDataRequestCultureProvider() {
                Options = options } };

        applicationBuilder.UseRequestLocalization(options);
    }
}

Ara yazılımı çalıştırmak için öğesini MiddlewareFilterAttribute kullanın:

[Route("{culture}/[controller]/[action]")]
[MiddlewareFilter(typeof(LocalizationPipeline))]
public IActionResult CultureFromRouteData()
{
    return Content(
          $"CurrentCulture:{CultureInfo.CurrentCulture.Name},"
        + $"CurrentUICulture:{CultureInfo.CurrentUICulture.Name}");
}

Ara yazılım filtreleri, filtre işlem hattının Kaynak filtreleri ile aynı aşamasında, model bağlamadan önce ve işlem hattının geri kalanından sonra çalışır.

İş parçacığı güvenliği

Filtrenin bir örneğini yerine içine TypeAddgeçirirken, filtre tekildir ve iş parçacığı açısından güvenli değildir.

Sonraki eylemler

  • Bkz. Sayfalar için Razor filtreleme yöntemleri.
  • Filtrelerle deneme yapmak için GitHub örneğini indirin, test edin ve değiştirin.