You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:35:00