23 Ağustos 2021

ASP.NET Core Middleware Response Body Değiştirme

using Sample.Settings;
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Threading.Tasks;

namespace Sample.Middlewares
{
    public class ContentModifyMiddleware
    {
        private readonly RequestDelegate next;
        private readonly MySettings mySettings;
        public ContentModifyMiddleware(RequestDelegate next,
            MySettings mySettings)
        {
            this.next = next;
            this.mySettings = mySettings;
        }

        public async Task Invoke(HttpContext context)
        {
            // Başlangıç: Hangi Koşullarda Değiştireceğim (Opsiyonel)
            var modifyBody = false;
            object controllerName = null;
            modifyBody = (context.Request.RouteValues != null
                && context.Request.RouteValues.TryGetValue("controller", out controllerName)
                && mySettings.ReplaceTexts != null
                && mySettings.ReplaceTexts.Count > 0);
            modifyBody &= (controllerName != null && controllerName.ToString() == "Home");
            // Bitiş: Hangi Koşullarda Değiştireceğim (Opsiyonel)
          
            // Başlangıç: İçerik Değiştirilsin
            if (modifyBody)
            {
                // Orjinal Body Yedekle
                var originalBody = context.Response.Body;
               
                // Değişikliklerin Yapılacağı Yeni Body
                var newBody = new MemoryStream();
                context.Response.Body = newBody;

                // Response'u al
                await next(context);

                // Responsu string olarak oku
                newBody.Position = 0;
                var newContent = await new StreamReader(newBody).ReadToEndAsync();

                // Başlangıç: Response Üzerinde Değişiklikeri Yap
                // (Replace alanlarını appsettings.json dan okuyorum - siz gömülü kod kullanabilirsiniz.)
                foreach (var item in mySettings.ReplaceTexts)
                {
                    newContent = newContent.Replace(item.Old, item.New);
                }
                // Başlangıç: Response Üzerinde Değişiklikeri Bitiş
               
                //String üzerinde yapılan değişiklikler tekrar stream'a dönüştürülüyor. Ve değiştirilmiş stream original body ile değiştiriliyor.
                using (var stream = new MemoryStream())
                {
                    var writer = new StreamWriter(stream);
                    writer.Write(newContent);
                    writer.Flush();
                    stream.Position = 0;
                    await stream.CopyToAsync(originalBody);
                }
                newBody.DisposeAsync();
                context.Response.Body = originalBody;
            }
            // Bitiş: İçerik Değiştirilsin
            // Başlangıç: İçerik Değiştirilmeden Geç
            else
            {
                await next(context);
            }
            // Bitiş: İçerik Değiştirilmeden Geç
        }
    }
}