در Asp.net core توسط IHttpContextAccessor میتوان بهراحتی به HttpContext در هرجای برنامه دسترسی داشت و اطلاعات مورد نیاز را از قبیل نام کاربری، کوکیها، توکنها و ... به دست آورد. اما در Blazor Server برای استفاده از این قبیل اطلاعات توصیه شدهاست که اکیدا از IHttpContextAccessor در هرجایی از برنامه استفاده نشود؛ زیرا هیچ تضمینی وجود ندارد که در حالتهای مختلف، مقدار HttpContext معتبر باشد. برای کسب اطلاعات بیشتر در این باب میتوانید به Blazor and shared state و Accessing HttpContext.Items fails on WebKit browsers مراجعه نمایید. درکل Blazor Server خارج از چارچوب خط لوله ASP.NET Core اجرا میشود. اما اگر به هر دلیلی به دنبال اطلاعات خاصی از HttpContext در کامپوننتها باشیم چطور؟ آیا هیچ راهی وجود ندارد؟
همانطور که ملاحظه مینمایید اطلاعات توکن access_token را داخل متغیر token ریخته و آنرا به param-AccessToken کامپوننت منتسب میکنیم.
در پایان، هر کامپوننتی که نیاز به مقدار AccessToken را داشته باشد فقط کافیست آنرا به عنوان یک Cascade Parameter تعریف کند. برای مثال یک کامپوننت را به نام ShowToken.razor ایجاد میکنیم و کدهای آنرا مانند زیر قرار میدهیم.
بدیهی است که اطلاعات دیگری نیز میتوان از HttpContext استخراج کرد. برای مثال شاید شما بخواهید که در یک کامپوننت، بدون استفاده از <AuthorizeView> نام کاربری شخصی که لاگین کرده است را به دست آورید (برای زمانی که از اعتبارسنجی مبتنی بر کوکیها در ASP.NET Core 2.0 بدون استفاده از سیستم Identity استفاده میکنید). تنها کافیست بخش Host.cshtml_ را مانند زیر تغییر دهید.
برای دستیابی به HttpContext در Blazor Server فقط باید در زمان رندر شدن Host.cshtml_ مقدار(های) مدنظر را از HttpContext دریافت کرده و داخل متغیری ذخیره کنیم و در ادامهی برنامه از آن متغیر در قالب Cascading Parameters در کامپوننتها استفاده نماییم.
روش کار به اینصورت است که ابتدا فایل Host.cshtml_ را به شکل زیر اصلاح میکنیم. در اینجا ما به دنبال اطلاعات توکن access_token میباشیم.
@{ var token = await HttpContext.GetTokenAsync("access_token"); } <component type="typeof(App)" render-mode="ServerPrerendered" param-AccessToken="token" />
سپس به فایل App.razor رفته و متغیر AccessToken را به عنوان یک Cascading Value تعریف میکنیم. به شکل زیر:
<CascadingValue Name="AccessToken" Value="AccessToken"> <CascadingAuthenticationState> <Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> </CascadingAuthenticationState> </CascadingValue> @code{ [Parameter] public string AccessToken { get; set; } }
@page "/showtoken" <p>This is part of the access token @(AccessToken != null ? AccessToken.Substring(0,30) : "(null)")</p> @code { [CascadingParameter(Name = "AccessToken")] public string AccessToken { get; set; } }
var userName = await HttpContext.User.Identity.Name;
یا برای مثال اگر به دنبال اطلاعات یک کوکی خاص میباشید:
var khasCookie = HttpContext.Request.Cookies["khas"];