一种可能的方法是模仿 ASP.net 网络表单的遗留会话变量。这些依赖于没有过期日期的 cookie。 cookie 的生命周期也等于浏览器会话的生命周期。
主要工作是在 _Host.cshtml 中完成,我们将在其中创建一个用作会话标识符的 guid。此 guid 对整个浏览器会话(所有选项卡)都有效。
- 创建此属性:
public Guid NewGuid { get; } = Guid.NewGuid();
- 注入 HttpContextAccessor :
public HostModel(IHttpContextAccessor httpContextAccessor)
- 获取cookie值:
string g = httpContextAccessor.HttpContext.Request.Cookies["SessionGuid"] ?? "";
if (Guid.TryParse(g, out Guid guid))
request.SessionGuid = guid;
else
request.SessionGuid = NewGuid
在此代码中,request 是一个级联参数,将传递给所有组件。
在标记中,您将其添加到正文中
<script>createSessionGuid('@Model.NewGuid');</script>
这使用了这个必须加载的小javascript函数:
function createSessionGuid(newguid) {
var current = getCookie("SessionGuid");
if ((current === null) || (current === "")) {
var guid = newguid;
document.cookie = "SessionGuid=" + guid + "; path=/";
console.log("SessionGuid created : " + guid);
}
else {
console.log("SessionGuid found : " + current);
}
}
通过这种方式,您无需使用 JSInterop 即可获得会话 ID,因此无需使用任何异步代码。
故事的其余部分非常简单:只需创建一个会话类,它是一个字典字典(并发字典)。顶级字典中的键应该是会话 ID。二级字典中的键就是会话变量名。
编辑:如何在_Host.cshtml中使用CascadingValue?
在_Host.cshtml中:见最后一个参数。
<component type="typeof(App)" render-mode="ServerPrerendered" param-Request="Model.request" />
在 _Host.cshtml 的代码隐藏中
public BaseClasses.Request request;
public HostModel(IHttpContextAccessor httpContextAccessor)
{
request = new BaseClasses.Request();
httpContextAccessor.HttpContext.Request.Cookies.Where(kvp => kvp.Key != "SessionGuid").ToList().ForEach(kvp => request.Cookies.Add(kvp.Key, kvp.Value));
string g = httpContextAccessor.HttpContext.Request.Cookies["SessionGuid"] ?? "";
if (Guid.TryParse(g, out Guid guid))
request.SessionGuid = guid;
else
request.SessionGuid = NewGuid;
}
此信息在 MainLayout.razor.cs 中检索并开始级联。
[CascadingParameter]
private BaseClasses.Request Request { get; set; }