Ana Sayfa Hakkımda Dersler Blog MikrofondaOn The Mic İletişim Projeler Yakında
DerslerLessons ASP.NET CORE · C#

ASP.NET Core — Action Filter ile Stok Kontrolü ASP.NET Core — Stock Control with Action Filters

9 dk okuma 9 min read · Emre Ulutabak
1
Action Filter nedir? What is an Action Filter?

Bir kullanıcı bir sayfaya gitmek istediğinde bazen action çalışmadan önce bazı kontroller yapmak isteriz. Mesela ürün stokta mı, kullanıcı aktif mi, üyelik geçerli mi?

Bu tür ortak kontrolleri her action içine tekrar tekrar yazmak yerine Action Filter kullanırız.

Action Filter, controller action çalışmadan önce devreye giren bir ara kontrol katmanıdır.

When a user tries to access a page, sometimes we want to run checks before the action executes. For example: is the product in stock, is the user active, is the membership valid?

Instead of repeating those checks inside every action, we use an Action Filter.

An Action Filter is an intermediate control layer that runs before the controller action executes.

💡
Aynı kontrol birçok action’da tekrar ediyorsa, filter iyi bir adaydır. If the same check repeats across many actions, a filter is a strong candidate.
2
Hikaye: Kafedeki sipariş ekranı Story: The cafe order screen

Şimdi farklı bir örnek düşünelim. Bir kafe otomasyonunda müşteri ekrandan kahve siparişi verecek.

Ama bazı içecekler tükenmiş olabilir. Kullanıcı sipariş sayfasına girmeden önce sistem, seçilen ürünün stokta olup olmadığını kontrol etmek istiyor.

Eğer stok varsa devam edilir. Yoksa kullanıcı boşuna forma girmez; doğrudan OutOfStock sayfasına yönlendirilir.

İşte bu kontrolü action içine tek tek yazmak yerine bir filter ile merkezi hale getirebiliriz.

Now imagine a different example. In a cafe system, a customer wants to place a coffee order from a screen.

But some drinks may be out of stock. Before the user enters the order page, the system wants to check whether the selected product is available.

If stock exists, the request continues. If not, the user is redirected directly to the OutOfStock page instead of opening a useless form.

Instead of writing this check inside every action, we can centralize it with a filter.

3
Neden gerekli? Why is it needed?

Diyelim ki sipariş oluşturma, hızlı sipariş, kampanyalı sipariş ve mobil sipariş gibi birden fazla action’ın var. Hepsinde aynı stok kontrolünü tekrar etmek kodu uzatır.

Üstelik bir gün kural değişirse hepsini tek tek düzenlemek gerekir.

Filter kullanınca bu kuralı tek yere koyarsın. Böylece hem tekrar azalır hem de kod daha okunur olur.

Suppose you have multiple actions such as create order, quick order, discounted order, and mobile order. Repeating the same stock check in all of them makes the code longer.

And if the rule changes one day, you would need to update all of them one by one.

With a filter, you place the rule in one location. That reduces repetition and makes the code easier to read.

4
Kısa örnek A short example

Aşağıdaki örnekte filter, action’a gelen productId değerini alıyor. Sonra stok servisine soruyor: “Bu ürün şu anda var mı?”

Eğer ürün yoksa kullanıcıyı başka sayfaya yönlendiriyor. Varsa action’ın çalışmasına izin veriyor.

In the example below, the filter reads the incoming productId value from the action. Then it asks the stock service: “Is this product currently available?”

If the product is unavailable, it redirects the user. Otherwise, it allows the action to run.

csharp
public class RequireStockFilter : IAsyncActionFilter
{
    private readonly IStockService _stockService;

    public RequireStockFilter(IStockService stockService)
    {
        _stockService = stockService;
    }

    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next)
    {
        var productId = context.ActionArguments["productId"] as int?;

        if (productId.HasValue)
        {
            var hasStock = await _stockService
                .HasStockAsync(productId.Value);

            if (!hasStock)
            {
                context.Result = new RedirectToActionResult(
                    "OutOfStock",
                    "Shop",
                    null);
                return;
            }
        }

        await next();
    }
}
💡
Uzun satırları bölmek kod bloğunu daha temiz gösterir ve yatay scroll riskini azaltır. Breaking long lines makes code blocks cleaner and reduces the risk of horizontal scrolling.
5
context.Result mantığı The logic of context.Result

Filter içindeki en önemli fikirlerden biri şudur: Eğer context.Result verirsen action artık çalışmaz.

Yani sistem “buradan sonrası iptal, sonucu ben belirledim” demiş olur.

Biz de bunu stok yoksa kullanıcıyı başka sayfaya göndermek için kullanıyoruz.

One of the most important ideas in a filter is this: if you assign context.Result, the action no longer executes.

In other words, the system says: “The rest is cancelled, I have already decided the result.”

We use that behavior to redirect the user when the product is out of stock.

csharp
context.Result = new RedirectToActionResult(
    "OutOfStock",
    "Shop",
    null);
return;
💡
context.Result akışı keser, await next() ise akışı devam ettirir. context.Result stops the flow, while await next() allows it to continue.
6
Controller üzerinde kullanım Usage on the controller

Bu filter’ın en güçlü tarafı burada görülür. Controller üzerine bir kez eklediğinde, ilgili action’lar bu kuraldan otomatik geçer.

Böylece action içinde tekrar stok kontrolü yazmana gerek kalmaz.

This is where the real power of the filter appears. Once attached to the controller, the relevant actions automatically pass through that rule.

That means you no longer need to repeat the stock-check logic inside each action.

csharp
[ServiceFilter(typeof(RequireStockFilter))]
public class OrderController : Controller
{
    [HttpGet]
    public IActionResult Create(int productId)
    {
        return View();
    }
}

Burada kullanıcı Create action’ına gitmek istediğinde önce filter çalışır. Ürün uygunsa action açılır, değilse kullanıcı yönlendirilir.

Here, when the user tries to access the Create action, the filter runs first. If the product is valid, the action opens; otherwise, the user is redirected.

7
Altın kurallar Golden rules

Action Filter yazarken sadece teknik olarak çalışan bir yapı kurmak yetmez. Aynı zamanda neden burada olduğunu da net anlatabilmelidir.

İyi bir filter, tekrar eden kontrolü tek noktaya toplar ve controller’ı sade bırakır.

When writing an Action Filter, it is not enough for it to merely work technically. Its purpose should also be easy to understand.

A good filter centralizes repeated checks and keeps the controller clean.

💡
Filter’ı, bir action’dan çok bir kuralın evi gibi düşün. Think of a filter not as part of a single action, but as the home of a rule.
💡
Tekrar eden kontrol varsa merkezi hale getirmek çoğu zaman daha iyidir. If a check repeats often, centralizing it is usually the better choice.
💡
Kod örneklerinde kısa satırlar kullanmak hem okunurluğu hem görsel düzeni iyileştirir. Using shorter lines in code examples improves both readability and visual layout.
MİNİ QUIZ MINI QUIZ
Aşağıdakilerden hangisi doğrudur? Which of the following is correct?
Action Filter sadece veritabanı tabloları oluşturur An Action Filter only creates database tables
Action Filter, action çalışmadan önce ortak kontrol yapmak için kullanılabilir An Action Filter can be used to run shared checks before an action executes
context.Result verilirse action yine de kesin çalışır If context.Result is assigned, the action will still definitely run
ServiceFilter sadece JavaScript dosyalarında kullanılır ServiceFilter is only used in JavaScript files