Erhan Ballıeker

Asp.Net Core DelegatingHandler

Selamlar,

Son yazılarımda Asp.Net Core 2.1 ile gelen HttpClientFactory ve bu api ın çeşitli kütüphaneler ile kullanımından bahsetmiştim.

Bu yazımda da yine clientfactory ile alakalı olarak DeletagingHandler dan bahsetmek istiyorum. Daha önce de çeşitli yollarla muhtemelen yapmış olduğunuz bir şeyi delegatinghandler lar ile nasıl daha kolay yapabiliriz bunu görücez.

DelegatingHandler için ilk söyleyeceğim şey Asp.Net Core daki Middleware yapısına olan benzerliğidir. Middleware yapısında nasıl ki browserdan server mıza kadar gelen request in yaşam döngüsü içerisinde, Kestret ayağa kalktıktan sonra, request in geçeceği middleware leri ayarlıyorsak, burada da aynı şekilde, HttpClientFactory ile request attığımız client ımız için, gidecek olan request in arasına istediğimiz şekilde ve farklı delegatinghandler la ile girip, request i yarı da kesmekten tutun da, response ı tamamen değiştirmeye kadar herşeyi yapabiliyoruz.

Aşağıda basit bir DelegatingHandler örneğine bakalım.

   public class AuthTokenHandler : DelegatingHandler
    {
        private readonly string _token;
        private const string TOKEN = "Authorization";
        public AuthTokenHandler(string token)
        {
            _token = token;
        }

        protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (!request.Headers.Contains(TOKEN) && string.IsNullOrEmpty(_token))
            {
                return new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    Content = new StringContent("Missing auth token.")
                };
            }
            else if (!request.Headers.Contains(TOKEN) && !string.IsNullOrEmpty(_token))
            {
                request.Headers.Add(TOKEN, $"Bearer {_token}");
            }

            var response = await base.SendAsync(request, cancellationToken);

            return response;
        }
    }

Yukarıda yazılan DelegatingHandler ı inceleyelim.

  • Yazdığımız DelegatingHandler ımız  DelegatingHandler sınıfından türemek durumunda
  • protected override async Task SendAsync metodunun override ederek istediğimiz işlemleri request in öncesi ve sonrasında yapabiliyoruz.
  • Bu metod içerisinde await base.SendAsync(request, cancellationToken); 
    • kodundan önceki kodlar request üzerinde yapacağımız işlemler
    • sonraki kodlar ise gelen response üzerinde yapmak isteyeceğimiz kısımlardır.
  • Bu handler ımız gelen request içerisinde Authorization isminde bir header arıyor. Eğer bu handler a paramere olarak geçilmiş olan token değerini bulamaz ise geriye request i bir sonraki aşamaya bile göndermeden(tıpkı middleware lardki shorcut yapısı gibi) geriye doğrudan response u dönüyor.
  • Eğer handler a geçilen parametre boş değilse bir token değeri varsa bu token değerini, Authorization header içerisine Bearer token olarak koyuyor.

Bu şekilde bir api ile haberleşirken sıkça karşılaşığımız gibi token based authantication yönetimi için her bir request ile header da token yollama işini çok basit şekilde halledebilmiş oluyoruz.

Peki bu yazmış olduğumuz Delegating handler ı request in pipeline ına nasıl ekleyeceğiz buna bakalım.

   public void ConfigureServices(IServiceCollection services)
        {
            services.Configure(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddTransient<AuthTokenHandler>();
            services.AddHttpClient("randomuserclient", client =>
            {
                client.BaseAddress = new Uri("https://randomuser.me/api");
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactoryTesting");
            })
            .AddHttpMessageHandler<AuthTokenHandler>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

Geçtiğimiz yazılarımızda HttpClientFactory ve bunun asp.net core projelerinde kullanımına değindiğim için fazla detaya girmeyeceğim bu tarafta.

Buradan httpclientfactory ile ilgili yazdığım yazıların detaylarına ulaşabilirsiniz

Burada basitçe bir namedclient kullanıp services e randomuserclient adında bir client ekliyoruz, ve en son noktada, clientfactory ile ilgili tüm ayarlamalarımızı yaptıktan sonra

.AddHttpMessageHandler<AuthTokenHandler>();

diyerek request pipeline ına bu handler ı eklemiş oluyoruz.

Bir dikkat etmemiz gereken noktada şu;

AddHttpMessageHandler demeden önce bu handler ı ekleyebilmek için, handler ın kendisini de önceden asp.net core dependency injection mekanizmasına tanıtmamız gerekiyor, bunun için de;

services.AddTransient<AuthTokenHandler>();

diyerek, container a bu sınıfımızı da ekliyoruz.

Aşağıda da her zaman olduğu client factory mizi kullanabiliriz. Burada önceki kullanım şekillerine göre hiçbir fark yok (NamedClient olarak eklediğimiz için yine CreateClient derken randomuserclient şeklinde ismini vererek çağırıyoruz.)

public class HomeController : Controller
    {
        private readonly IHttpClientFactory _httpClientFactory;
        public HomeController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public async Task Index()
        {
            var client = _httpClientFactory.CreateClient("randomuserclient");
            var result = await client.GetStringAsync("?results=5");
            return View();
        }

Bir sonraki yazımda birden fazla DelegatingHandler eklediğimiz durumlarda işler nasıl oluyor buna bakacağız.

Bir sonraki yazımda görüşmek üzere.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

%d blogcu bunu beğendi: