Asp.NET Core’da Route Handler Oluşturma

Merhaba,

Asp.NET Core uygulamalarında kendi route handler yapılanmamızı oluşturarak belli başlı isteklere özel cevaplar verebiliriz. Aslında bizler bu konuya dair önceden Asp.NET MVC’de HttpHandler Oluşturma başlığı altında bir değerlendirmeyi standart Asp.NET MVC için kaleme almış bulunmaktayız. Bu içeriğimizde ise benzer yapılanmayı Asp.NET Core uygulaması için nasıl gerçekleştireceğimizi; konuyu daha geniş değerlendirerek, Core çekirdeği çerçevesinde daha fazla muhakeme ederek inceleyeceğiz.

İlk olarak Asp.NET Core mimarisinde bir request sürecinde hangi adımların gerçekleştiğini hatırlayarak, ilgili konumuzun kuramsal temelini oluşturalım. Ardından route handler yapılanmasının hangi kurallar çerçevesinde, nasıl sağlanacağını inceleyerek bir image boyutlandırma kurgusu üzerinden örneklendirme yapıp makalemizi noktalayalım.

Asp.NET Core'da Route Handler Oluşturma

Request sürecinde neler oluyor?

  • Web sunucusuna istek gelir,
  • Varsa middleware‘ler devreye girer, sırasıyla tek tek işlenir,
  • Taa ki sıra route middlewareimiz olan UseMvcWithDefaultRoute yahut UseMvc middlewarelerine gelir. Bir başka deyişle yönlendirme katmanı tetiklenirde diyebiliriz.
  • Yönlendirme katmanı, gelen isteği önceden tanımlanmış yahut varsayılan olarak belirtilmiş şemalarla eşleşip eşleşmediğini inceleyecek ve duruma göre yönlendirmede bulunacaktır.

süreçteki genel olaylar bu çerçevede ceyran etmektedir.

İşte bu işleyişin son basamağında, süreçte en son route handler dediğimiz noktaya temas edilecektir. Burada eşleşen şemalara karşı route mekanizmaları handler edilerek gerekli yönlendirmeler response edilecektir.

Bizler klasik route şemaları oluşturmak yerine custom route handler yapıları inşa ederek bu son noktada devreye sokabiliriz. Dolayısıyla kendimize özel istekler tanımlayabilir ve farklı işlemlere tabi tutulan yönlendirmelerde bulunabiliriz. Tüm bu yapılanmayı custom route handler oluşturarak gerçekleştirebiliriz ve bunu yaparken Asp.NET Core mimarisinde, standart Asp.NET MVC mimarisindeki yaptığımız çalışmadan oldukça farklı ve sade bir şekilde çaba göstererek sağlayabiliriz.

Peki custom route handler nasıl oluşturulur?
Bunun için tek yapılması gereken “RequestDelegate” isimli delegate’i geriye dönen metot tasarlamaktadır.

    public class ExampleHandler
    {
        public RequestDelegate Handler()
        {
            return async c => await Task.Run(async () =>
            {
                await c.Response.WriteAsync("hello world");
            });
        }
    }

İşte bu kadar… Ne kadar basit değil mi? Ekrana “hello world” yazacak custom route handler’ımızı oluşturmuş olduk. Şimdi bu oluşturmuş olduğumuz route handler’ı kullanabilmek için route şemalarında aşağıdaki gibi belirtmemiz yeterli olacaktır.

    public class Startup
    {
        IHostingEnvironment _hostingEnvironment;
        public Startup(IHostingEnvironment hostingEnvironment) => _hostingEnvironment = hostingEnvironment;

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();

            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();
            app.UseMvc(routes =>
            {
                routes.MapRoute("customroute", new ExampleHandler().Handler());
                routes.MapRoute(
                    name: "Default",
                    template: "{controller=Home}/{action=Index}/{id?}"
                    );
            });

        }
    }

Yukarıdaki kod bloğunu incelerseniz eğer oluşturduğumuz custom route handler’ı nerede kullandığımızı belki direkt olarak yakalayamayabilirsiniz. O yüzden daha net odaklanabilmek için ilgili satırları sade bir şekilde aşağıya alıyorum…

.
.
.
            app.UseMvc(routes =>
            {
                routes.MapRoute("customroute", new ExampleHandler().Handler());
                routes.MapRoute(
                    name: "Default",
                    template: "{controller=Home}/{action=Index}/{id?}"
                    );
            });
.
.
.

Evet… Görüldüğü üzere tanımladığımız route handler’ımız, “customroute” şeklinde tanımlanmış bir route üzerinde handler edilmektedir.
Asp.NET Core'da Route Handler Oluşturma

İşte bu kadar basit…

Şimdi bu temelde image boyutlandırma üzerine örneklendirme ile konumuzu zenginleştirip, makalemizi noktalayabiliriz.

Custom Route Handler İle Image Boyutlandırma

    public class ImageHandler
    {
        IHostingEnvironment _hostingEnvironment;
        public ImageHandler(IHostingEnvironment hostingEnvironment) => _hostingEnvironment = hostingEnvironment;
        public RequestDelegate Handler()
        {
            return async c => await Task.Run(async () =>
            {
                string fileName = c.GetRouteValue("fileName").ToString();

                FileInfo imageFile = new FileInfo($"{_hostingEnvironment.WebRootPath}\\{fileName}");

                using (MagickImage magicImage = new MagickImage(imageFile))
                {
                    int width = magicImage.Width, height = magicImage.Height;

                    if (!string.IsNullOrEmpty(c.Request.Query["w"].ToString()))
                        width = int.Parse(c.Request.Query["w"].ToString());
                    if (!string.IsNullOrEmpty(c.Request.Query["h"].ToString()))
                        height = int.Parse(c.Request.Query["h"]);


                    magicImage.Resize(width, height);
                    var buffer = magicImage.ToByteArray();
                    c.Response.Clear();
                    c.Response.ContentType = string.Concat("image/", imageFile.Extension.Replace(".", ""));
                    await c.Response.Body.WriteAsync(buffer, 0, buffer.Length);
                }

                await c.Response.WriteAsync($"{_hostingEnvironment.WebRootPath}\\{fileName}");
            });
        }
    }

Yukarıdaki “ImageHandler” isimli custom route handler’ı incelerseniz eğer tetiklendiği özel yönlendirici üzerinde gelen bazı route ve querystring parametreleri eşliğinde görseli boyutlandırmakta ve ContentType değerini gelen görselin extensionına uygun bir şekilde ayarlayarak response etmektedir. Ayrıca resim dosyaları üzerinde işlem yapabilmek içinde MagicImage kütüphanesi kullanılmaktadır.

İlgili custom route handler’a özel olarak aşağıdaki gibi bir route tanımlayalım.

    public class Startup
    {
        IHostingEnvironment _hostingEnvironment;
        public Startup(IHostingEnvironment hostingEnvironment) => _hostingEnvironment = hostingEnvironment;

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();

            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();
            app.UseMvc(routes =>
            {
                routes.MapRoute("image/{fileName}", new ImageHandler(_hostingEnvironment).Handler());
                routes.MapRoute(
                    name: "Default",
                    template: "{controller=Home}/{action=Index}/{id?}"
                    );
            });
        }
    }

Bu işlemden sonra aşağıdaki ekran görüntüsünde görüldüğü üzere ilgili route image ContentType’ında response edilmektedir.
Asp.NET Core'da Route Handler Oluşturma

Ayrıca bu şekilde handler edilen image nesneleri <img src=”…”  /> html nesnesinde direkt olarak kaynak olarak belirtilebilir ve dolayısıyla dinamik bir şekilde resim yapılanmasıda kullanılabilir şekilde ayarlanmış olur.

<img src="https://localhost:5001/image/image-1.jpg?w=200&h=250" />
<img src="https://localhost:5001/image/image-2.jpg?w=300&h=350" />
<img src="https://localhost:5001/image/image-3.jpg?w=400&h=450" />

Asp.NET Core'da Route Handler Oluşturma
Görüldüğü üzere…

İlgilenenlerin faydalanması dileğiyle…

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim.

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*