Blazor Server中如何隐式传递页面参数且不暴露于URL?
Blazor Server 隐藏参数传递方案
以下是几种无需暴露参数在URL中的实现方法,根据场景选择即可:
1. Scoped状态服务传递参数
通过注册Scoped级别的状态容器,在导航前存储参数,目标页面从容器中读取。Scoped服务会绑定单个用户会话,不会出现数据串用问题。
步骤:
- 定义状态服务类:
public class ParameterStore { public int Id { get; set; } public int AnotherId { get; set; } }
- 在
Program.cs注册为Scoped服务:
builder.Services.AddScoped<ParameterStore>();
- 发起导航的页面注入服务并设置参数:
@inject ParameterStore ParamStore @inject NavigationManager NavManager <button @onclick="GoToTargetPage">跳转至目标页</button> @code { private void GoToTargetPage() { ParamStore.Id = 21; ParamStore.AnotherId = 321; NavManager.NavigateTo("/books"); } }
- 目标页面注入服务读取参数:
@inject ParameterStore ParamStore <p>ID:@ParamStore.Id,AnotherID:@ParamStore.AnotherId</p>
注意:用户直接刷新目标页面时,参数会丢失,适合无需持久化参数的场景。
2. ASP.NET Core Session存储参数
利用Session存储参数,参数会保留到Session超时,刷新页面也不会丢失。
步骤:
- 在
Program.cs启用Session并注册IHttpContextAccessor:
builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); options.Cookie.HttpOnly = true; }); builder.Services.AddHttpContextAccessor(); // 中间件顺序:放在UseRouting之后,UseBlazorFrameworkComponents之前 app.UseSession();
- 发起导航的页面写入Session:
@inject IHttpContextAccessor HttpContextAccessor @inject NavigationManager NavManager <button @onclick="NavigateWithSession">跳转</button> @code { private void NavigateWithSession() { var session = HttpContextAccessor.HttpContext.Session; session.SetInt32("TargetId", 21); session.SetInt32("AnotherTargetId", 321); NavManager.NavigateTo("/books"); } }
- 目标页面读取Session:
@inject IHttpContextAccessor HttpContextAccessor @code { private int? Id { get; set; } private int? AnotherId { get; set; } protected override void OnInitialized() { var session = HttpContextAccessor.HttpContext.Session; Id = session.GetInt32("TargetId"); AnotherId = session.GetInt32("AnotherTargetId"); // 可选:读取后清除Session避免残留 // session.Remove("TargetId"); // session.Remove("AnotherTargetId"); } }
3. 加密查询参数(折中方案)
如果可以接受URL存在加密后的字符串,可将参数加密后作为查询参数传递,用户无法直接识别原始参数。
示例:
- 实现加密/解密工具类(需自行确保密钥安全):
public static class ParamEncryptor { // 示例加密逻辑,实际需使用标准加密算法如AES public static string Encrypt(int id, int anotherId) { var rawData = $"{id}:{anotherId}"; // 此处替换为真实加密逻辑 return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(rawData)); } public static (int Id, int AnotherId) Decrypt(string encryptedData) { var rawData = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(encryptedData)); var parts = rawData.Split(':'); return (int.Parse(parts[0]), int.Parse(parts[1])); } }
- 导航前加密参数:
@inject NavigationManager NavManager <button @onclick="NavigateWithEncryptedParams">跳转</button> @code { private void NavigateWithEncryptedParams() { var encrypted = ParamEncryptor.Encrypt(21, 321); NavManager.NavigateTo($"/books?data={encrypted}"); } }
- 目标页面解密参数:
@inject NavigationManager NavManager @code { private int Id { get; set; } private int AnotherId { get; set; } protected override void OnInitialized() { var query = new Uri(NavManager.Uri).Query; var encryptedData = System.Web.HttpUtility.ParseQueryString(query).Get("data"); if (!string.IsNullOrEmpty(encryptedData)) { var (id, anotherId) = ParamEncryptor.Decrypt(encryptedData); Id = id; AnotherId = anotherId; } } }
内容的提问来源于stack exchange,提问作者Sarcovitz
相关产品推荐
相关产品推荐

