Blazor WASM如何将查询字符串绑定到Dictionary<string, string>
在Blazor WASM中实现筛选器与查询参数的双向绑定(转为Dictionary<string, string>)
要实现筛选器变更时同步更新URL查询参数,同时支持从URL参数还原筛选状态,你可以按照以下步骤操作:
1. 注入核心服务
在页面组件中注入NavigationManager,它负责Blazor的导航和URL操作:
@inject NavigationManager NavManager @implements IDisposable
2. 定义筛选器模型与查询参数字典
创建对应UI筛选控件的模型类,同时维护存储查询参数的Dictionary<string, string>:
// 筛选器模型,对应页面上的输入控件 private FilterModel Filters { get; set; } = new FilterModel(); // 存储查询参数的字典,用于生成URL private Dictionary<string, string> QueryParams { get; set; } = new(); public class FilterModel { public string Name { get; set; } = string.Empty; public bool? HasRole { get; set; } // 根据需求添加其他筛选字段,如年龄范围、状态等 }
3. 初始化:从URL读取查询参数
页面初始化时,解析当前URL的查询参数,同步到字典和筛选器模型,再加载对应数据:
protected override void OnInitialized() { // 解析URL中的查询参数到字典 var uri = new Uri(NavManager.Uri); var parsedQuery = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query); QueryParams = parsedQuery.ToDictionary(kv => kv.Key, kv => kv.Value.ToString()); // 将字典值映射到筛选器模型 if (QueryParams.TryGetValue("name", out var name)) Filters.Name = name; if (QueryParams.TryGetValue("hasRole", out var hasRoleStr) && bool.TryParse(hasRoleStr, out var hasRole)) Filters.HasRole = hasRole; // 加载初始数据 LoadFilteredData(); } // 模拟加载数据的方法 private void LoadFilteredData() { // 这里根据QueryParams或Filters发起数据请求 }
4. 筛选器变更时更新URL
当用户修改筛选控件时,更新查询参数字典并重新导航到带参数的URL:
private void OnFilterChanged() { // 清空旧参数,根据当前筛选器生成新参数 QueryParams.Clear(); if (!string.IsNullOrWhiteSpace(Filters.Name)) QueryParams["name"] = Filters.Name.Trim().ToLower(); if (Filters.HasRole.HasValue) QueryParams["hasRole"] = Filters.HasRole.Value.ToString().ToLower(); // 构建带新查询参数的URL var currentPath = new Uri(NavManager.Uri).PathAndQuery; var newUrl = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(currentPath, QueryParams); // 导航到新URL:forceLoad=false使用客户端导航,replace=true替换当前历史记录(避免返回栈堆积) NavManager.NavigateTo(newUrl, forceLoad: false, replace: true); }
5. 监听URL变化,同步筛选状态
当用户直接修改URL或通过分享链接打开页面时,监听导航事件,重新解析参数并更新筛选器和数据:
protected override void OnAfterRender(bool firstRender) { if (firstRender) { NavManager.LocationChanged += HandleLocationChanged; } base.OnAfterRender(firstRender); } private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) { // 重新解析URL参数 var uri = new Uri(e.Location); var parsedQuery = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query); QueryParams = parsedQuery.ToDictionary(kv => kv.Key, kv => kv.Value.ToString()); // 更新筛选器模型 Filters.Name = QueryParams.TryGetValue("name", out var name) ? name : string.Empty; Filters.HasRole = QueryParams.TryGetValue("hasRole", out var hasRoleStr) && bool.TryParse(hasRoleStr, out var hasRole) ? hasRole : null; // 重新加载数据 LoadFilteredData(); } // 组件销毁时取消事件订阅,避免内存泄漏 public void Dispose() { NavManager.LocationChanged -= HandleLocationChanged; }
6. UI绑定示例
将筛选控件与模型绑定,并在值变更时触发OnFilterChanged方法:
<div class="filter-container"> <input type="text" @bind="Filters.Name" @bind:event="oninput" @onchange="OnFilterChanged" placeholder="搜索用户名称..." class="form-control" /> <div class="form-check"> <input type="checkbox" @bind="Filters.HasRole" @onchange="OnFilterChanged" class="form-check-input" id="hasRoleCheck" /> <label class="form-check-label" for="hasRoleCheck">拥有应用角色</label> </div> </div> <!-- 数据表格 --> <table class="table mt-3"> <thead> <tr> <th>名称</th> <th>是否有角色</th> <!-- 其他列 --> </tr> </thead> <tbody> <!-- 渲染数据行 --> </tbody> </table>
关键细节说明
- 使用
Microsoft.AspNetCore.WebUtilities.QueryHelpers处理查询参数的解析与构建,这是ASP.NET Core内置工具类,无需额外引用。 NavManager.NavigateTo的replace: true参数:替换当前浏览器历史记录,避免用户多次点击返回按钮时重复遍历筛选状态。- 类型安全处理:解析布尔值等类型时要做合法性校验,避免无效参数导致异常。
- 组件销毁时取消
LocationChanged事件订阅,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Parsa99
相关产品推荐
相关产品推荐

