提问人:user4779 提问时间:1/17/2023 更新时间:6/12/2023 访问量:1399
如何通过 HttpContext 访问 Blazor Server .Net 6 中的 Cookie?
How do I access cookies in Blazor Server .Net 6 via HttpContext?
问:
遗憾的是,有关在 Blazor Server 中访问 Cookie 的教程和先前的 StackOverflow 答案似乎在新的 .Net 版本中失效。例如,我无法获得以下任何一个答案(从它们在 .net 6 中没有的注释来看): 如何在服务器端 Blazor 中使用 HttpContext 对象检索有关用户、用户代理的信息 如何在服务器端 Blazor 中访问 HttpContext?
我有一个包含以下代码的 Program.cs 文件:
..
builder.Services.AddHttpContextAccessor();
..
它还有一个应用程序。MapPost 方法,用于设置 cookie:HttpContext.Response.Cookies.Append
我可以确认cookie有效,因为在postman中,我可以在查询此应用程序时成功检索它。MapPost 方法。
尝试在 Login.Razor 页面中查询该方法时,它可以正常工作,但未设置 cookie。在此 Login.razor 中,httpContextAccessor.HttpContext.Request.Cookies[“my_cookie”] 始终返回 null(即使响应本身是 200 OK,并且我可以很好地读取其内容,没有可通过 HttpContext 检索的 cookie)。
这似乎是一个常见的问题,从两个链接的答案来看,这个问题已经解决,但现在在 .net 6 中似乎又坏了。如何在 Blazor Server .net 6 中访问 HttpContext 以访问查询中发送的 Cookie?
答:
请不要在 Blazor Server 中使用。AddHttpContextAccessor()
我在 中使用以下方法。净6:
我首先修改_Host.cshtml文件,如下所示。
@{
var myCookie = HttpContext.Request.Cookies["CookieName"];
}
<component type="typeof(App)" render-mode="ServerPrerendered" param-AccessToken="myCookie" />
我将 Cookie 信息放入 myCookie 变量中,并将其分配给组件的 .param-AccessToken
然后,我转到文件并将变量定义为级联值。如下:App.razor
AccessToken
<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>
@code{
[Parameter]
public string AccessToken { get; set; }
}
最后,任何需要 Cookie 信息值的组件只需要将其定义为级联参数即可。例如,我创建了一个名为的组件,并将其代码如下:ShowToken.razor
@page "/showtoken"
<p>This is a part of Cookie info @(AccessToken != null ? AccessToken.Substring(0,30) : "(null)")</p>
@code {
[CascadingParameter(Name = "AccessToken")] public string AccessToken { get; set; }
}
评论
<CascadingValue Name="AccessToken" Value="AccessToken">
</CascadingValue>
CascadingValue
AuthenticationStateProvider
在 .net6 及更高版本中,可以使用 Blazor 状态管理。
- 使用 localStorage 保持选项卡和浏览器实例之间的状态。
- 使用 sessionStorage 仅在选项卡/浏览器打开时保持状态。
localStorage 将是 AccessToken 的最佳选择。
在您想要访问存储的任何位置注入。组件/页面可以使用。
[Inject] ProtectedLocalStorage localStorage {get; set;}
或
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedLocalStorage localStorage
保存 AccessToken,如下所示:
await localStorage.SetAsync("AccessToken", "123");
要检索该值,请执行以下操作:
ProtectedBrowserStorageResult<string> storedResult = await localStorage.GetAsync<string>("AccessToken");
if (storedResult.Success)
{
string AccessToken = storedResult.Value.ToString();
}
警告:由于这在后台使用 Javascript,因此如果在组件渲染之前使用它,则会出现预渲染错误。两种选择:
在 _Host.cshtml 中,将呈现模式从“ServerPrerendered”更改为“Server”
<component type="typeof(App)" render-mode="Server" />
<component type="typeof(HeadOutlet)" render-mode="Server" />
或者,通过 OnAfterRenderAsync 检索值
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
ProtectedBrowserStorageResult<string> storedResult = await localStorage.GetAsync<string>("AccessToken");
if (storedResult.Success)
{
string AccessToken = storedResult.Value.ToString();
}
}
await base.OnAfterRenderAsync(firstRender);
}
评论