Blazor Server中MudDateRangePicker结合Web API查日期报错求助
MudBlazor日期范围筛选API请求400错误排查修复
核心问题分析及修复方案
1. 日期参数拼接错误(直接触发400的原因)
Blazor中DateRange是包含Start和End两个属性的结构体,直接对_dateRange使用格式化字符串会生成无效参数值,导致API无法解析。
修复后的ClearancePage.razor代码片段:
@page "/" @inject HttpClient HttpClient @inject NavigationManager Nav @inject ILocalStorageService localStorage @inject ISnackbar Snackbar <MudDateRangePicker @ref="_picker" Label="选择起止日期" @bind-DateRange="_dateRange"> <PickerActions> <MudButton Class="mr-auto align-self-start" OnClick="@(() => _picker.Clear())">清空</MudButton> <MudButton OnClick="@(() => _picker.Close(false))">取消</MudButton> <MudButton Color="Color.Primary" @onclick="SearchDate">确认</MudButton> </PickerActions> </MudDateRangePicker> @code{ private DateRange _dateRange = new DateRange(); private MudDateRangePicker _picker; private clearance[] clearancelist; private async Task SearchDate() { // 校验日期是否选择完整 if (!_dateRange.Start.HasValue || !_dateRange.End.HasValue) { Snackbar.Add("请选择完整的起止日期", Severity.Error); return; } var startDate = _dateRange.Start.Value.ToString("yyyy-MM-dd"); var endDate = _dateRange.End.Value.ToString("yyyy-MM-dd"); HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await localStorage.GetItemAsStringAsync("token")); HttpResponseMessage response = await HttpClient.GetAsync($"api/Clearance/SearchDateClearance?start={startDate}&end={endDate}"); if (response.IsSuccessStatusCode) { string contentrespose = await response.Content.ReadAsStringAsync(); clearancelist = JsonConvert.DeserializeObject<clearance[]>(contentrespose); } else { Snackbar.Add($"请求错误: {response.StatusCode}", Severity.Warning); } StateHasChanged(); } }
关键修改:
- 注入
HttpClient而非每次创建(符合ASP.NET Core最佳实践) - 分别提取
_dateRange.Start和_dateRange.End并格式化 - 添加日期完整性校验,避免无效请求
2. API路由与参数绑定问题
原Controller的HttpGet未指定明确路由,且未声明参数来源,可能导致路由匹配失败或参数绑定异常。
修复后的ClearanceController.cs代码:
[ApiController] [Route("api/[controller]")] public class ClearanceController : ControllerBase { private readonly ClearanceServices xservices; public ClearanceController(ClearanceServices services) { xservices = services; } [HttpGet("SearchDateClearance")] // 指定明确路由 public async Task<ActionResult<List<clearance>>> SearchDateClearance([FromQuery] DateTime start, [FromQuery] DateTime end) { try { var ret = await xservices.SearchDateClearance(start, end); return Ok(ret); } catch (Exception ex) { // 可添加日志记录 return BadRequest($"查询失败: {ex.Message}"); } } }
关键修改:
- 添加
[HttpGet("SearchDateClearance")]明确路由规则 - 使用
[FromQuery]指定参数来自URL查询字符串 - 用
ActionResult<T>包装返回值,统一错误响应格式 - 添加异常捕获并返回明确错误信息,便于排查
3. 数据库查询与异常处理优化
原Service中的异常处理为空,无法定位数据库层面的错误;同时日期参数可优化为仅传递日期部分,避免时间干扰。
修复后的ClearanceServices.cs代码片段:
public async Task<List<clearance>> SearchDateClearance(DateTime start, DateTime end) { List<clearance> xclearance = new(); try { // 仅保留日期部分,排除时间干扰 var startDate = start.Date; var endDate = end.Date; using (var con = new MySqlConnection(_constring.GetConnection())) { await con.OpenAsync().ConfigureAwait(false); var com = new MySqlCommand("SELECT * FROM clearance WHERE DATE(date) >= @start AND DATE(date) <= @end", con); com.Parameters.AddWithValue("@start", startDate); com.Parameters.AddWithValue("@end", endDate); using (var rdr = await com.ExecuteReaderAsync().ConfigureAwait(false)) { while (await rdr.ReadAsync().ConfigureAwait(false)) { xclearance.Add(new clearance { clear_id = Convert.ToInt32(rdr["clear_id"]), res_id = Convert.ToInt32(rdr["res_id"]), photo = (byte[])rdr["photo"], name = rdr["name"].ToString(), age = Convert.ToInt32(rdr["age"]), status = rdr["status"].ToString(), purok = rdr["purok"].ToString(), request = rdr["request"].ToString(), date = Convert.ToDateTime(rdr["date"]), fee = Convert.ToDouble(rdr["fee"]), receipt = rdr["receipt"].ToString(), }); } } } } catch (Exception ex) { // 注入ILogger记录日志 // _logger.LogError(ex, "日期范围查询失败"); throw; // 抛出异常让Controller统一处理 } return xclearance; }
关键修改:
- 提取日期的
Date部分,避免时间部分影响查询结果 - 移除不必要的
CommandType.Text和Parameters.Clear() - 优化类型转换方式,避免空值引发的异常
- 移除空异常处理,改为抛出异常让上层捕获处理
额外建议
- 确认数据库中
date字段类型为DATE或DATETIME,与查询逻辑匹配 - 可考虑使用
DateTimeOffset代替DateTime,避免时区问题 - 在Blazor页面中添加加载状态提示,提升用户体验
内容的提问来源于stack exchange,提问作者Xlayer
相关产品推荐
相关产品推荐

