در نوشته های پیشین نشان دادیم که میان افزارهای از پیش نوشته و آماده شده بدست IApplicationBuilder در دسترس هستند و همچنین متدهای ()Use و ()Run و ()Map نیز برای نوشتن میان افزار دلخواه از همین اینترفیس در دسترس هستند. در این نوشته می خواهیم نوشتن الگوی کلاسی برای میان افزار را نشان دهیم.

الگوی کلاس میان افزار

کد زیر الگوی یک کلاس میان افزار را نشان می دهد که در آغاز یک متغیر private readonly به نام next_ از نوع کلاس RequestDelegate ساخته می شود. سپس تابع سازنده کلاس نوشته می شود که یک پارامتر ورودی از نوع RequestDelegate دریافت کرده و درون بدنه آن، متغیر next_ مقدار دهی می شود.

کلاس میان افزار می تواند هر نامی داشته باشد و من نام MyCustomMiddleware را به کار برده ام. با RequestDelegate می توانیم درخواست های HTTP را پردازش کنیم. متد دیگر در کلاس میان افزار Invoke نام دارد که یک ورودی از نوع HttpContext را دریافت و یک نوع از Task را برگشت می دهد، بنابراین نیاز است تا دو فضای نام زیر به فایل کلاس افزوده شوند.

RequestDelegate و HttpContext در فضای نام Microsoft.AspNetCore.Http قرار دارند.

بدست آوردن رشته کوئری با کلاس HttpContext

در کد زیر می خواهیم کلاس میان افزاری بنویسیم که در آن بر روی همه درخواست ها بررسی شود که ایا در نشانی URL رشته کوئری دربرگیرنده کلید name مقداردهی شده است یا نه؟ رشته کوئری ویزگی است که به شیوه دوتایی های Key=Value به پایان رشته چسباندن می شوند و از این رو می توان به کمک URL ها، داده هایی را به سرور بفرستیم.

کلاس HttpContext همه اطلاعات درباره یک درخواست را در خود نگه می دارد و از این رو با ساختن نمونه ای از آن، می توانیم به داده های یک درخواست مانند مسیر (Path)، رشته کوئری (Query)، نوع محتوا (ContentType)، اندازه محتوا (ContentLength) و دیگر دسترسی داشته باشیم. توجه کنید اطلاعات درخواست به کمک ویژگی Request در دسترس است و از این رو است که به کمک دستور context.Request می توانیم به داده های یک درخواست دسترسی داشته باشیم.

در بَند (خط) ۱۷ از کد زیر به کمک Collection به نام Query، می توانیم به مقدار هر کلید در رشته کوئری چسبیده به پایان نشانی URL دسترسی داشته باشیم. توجه کنید Query برای این Collection است، زیرا که رشته کوئری می تواند دربرگیرنده یک تا چند دوتایی Key=Value باشد. برای نمونه در https://localhost:5001/Home/Privacy?name=amir رشته کوئری دارای یک کلید به نام name است و از این رو با فرستادن این نشانی، Query دارای یک کلید به نام name است که مقدار آن برابر با amir است.

 

برای نمونه در نشانی https://localhost:5001/Home/Privacy?name=amir&age=37، رشته کوئری دارای دو کلید به نام های name و age است و از این رو، Query نیز دارای دو کلید هم نام خواهد بود. در دو خط زیر فرض کردیم که رشته کوئری دارای همین دو کلید است و از این رو با کدهای زیر می توانیم به مقدار آنها دسترسی داشته باشیم. از اینجا می توانید بیشتر درباره کلاس HttpContext بدانید.

البته ممکن است که برای کلید name مقداری فرستاده نشود، پس میان افزار زمانی انجام می شود که مقداری برای کلید name تعیین شده باشد. کد زیر به کمک متد ()IsNullOrEmpty از کلاس string بررسی می کند که آیا متغیر queryString دارای مقدار است و زمانی دارای مقدار است که [“Query[“name دارای مقدار باشد و زمانی [“Query[“name دارای مقدار استکه در نشانی مقداری برای کلید name تعیین شده باشد.

کدهای زیر برجسته ترین بخش های کلاس میان افزار بالا هستند. نخست متغیری به نام responseString آماده می شود که رشته پاسخ را با کمک متد ()Format از کلاس string آماده می کند. سپس این متغیر به متد ()WriteAsync فرستاده می شود و در صورتی مقدار responseString نشان داده می شد که در هر URL رشته کوئری با کلید name و دارای مقدار فراهم شده باشد. در پایان دستور بند ۲۵ (await _next(context انجام می شود که در واقع این دستور میان افزار پَسین (بعدی) را فراخوانی می کند.

رجیستر کردن کلاس میان افزار در برنامه

گفتیم که متد ()Configure از کلاس Startup جایی است که میان افزارها در آن به برنامه افزوده می شوند و از این نیاز است تا ما نیز کلاس میان افزار دلخواه خودمان را نیز به این متد بی افزاییم تا در برنامه رجیستر شود. برای این باید از ()<UseMiddleware<MyMiddlewareClass کمک بگیریم که در آن MyMiddlewareClass نام کلاس میان افزار ما است. بنابراین باید کد زیر را در بَندی از فایل کلاس Startup و درون متد ()Configure بی افزاییم.

با این کار نوشتن و رجیستر کردن کلاس میان افزار به پایان رسیده است و اگر هر نشانی URL شناخته شده در برنامه که پایان آن رشته کوئری name=amir? باشد را به سرور بفرستیم، در واقع یک درخواست فرستاده ایم که یکی از میان افزارها برای آن شناخته شده است و از این رو واکنش پسندیده انجام می شود. برای نمونه من نشانی https://localhost:5001/Home/Privacy?name=amir را فرستاده ام. توجه کنید که یک درخواست به کمک نشانی URL به سرور فرستاده می شود برابر با نوشته مسیرها در ASP.NET Core MVC، این نشانی به یک الگو مسیر در برنامه نگاشت داده می شود.