在 Razor 页面中使用 DateTime 参数
Posted
技术标签:
【中文标题】在 Razor 页面中使用 DateTime 参数【英文标题】:Using DateTime Parameters in Razor Pages 【发布时间】:2021-01-02 05:36:26 【问题描述】:基本上我正在尝试为我的列表页面构建一个日期选择器过滤器。我首先使用了此处详述的搜索功能中的一些逻辑: https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-3.1#add-paging
我的 Get 方法的结构如下:
public async Task OnGetAsync(string sortOrder, string currentFilter, string searchString, int? pageIndex, string startDate, string endDate)
if (endDate==null)
endDate = TimeUtils.DateToString(DateTime.Now);
if (startDate==null)
startDate = TimeUtils.DateToString(DateTime.Now.AddDays(-60));
EndDate = TimeUtils.StringToDate(endDate);
StartDate = TimeUtils.StringToDate(startDate);
CurrentSort = sortOrder;
NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "Name";
DateSort = sortOrder == "Date" ? "" : "Date";
if (searchString != null)
pageIndex = 1;
else
searchString = currentFilter;
CurrentFilter = searchString;
IQueryable<Issue> issuesIQ = _context.Issue.Include(o => o.Agent);
if (!String.IsNullOrEmpty(searchString))
issuesIQ = issuesIQ.Where(o => o.Agent.ADAccount.Contains(searchString));
switch (sortOrder)
case "name_desc":
issuesIQ = issuesIQ.OrderByDescending(o => o.Agent.ADAccount);
break;
case "Date":
issuesIQ = issuesIQ.OrderBy(o => o.ContactDate);
break;
case "Name":
issuesIQ = issuesIQ.OrderBy(o => o.Agent.ADAccount);
break;
default:
issuesIQ = issuesIQ.OrderByDescending(o => o.ContactDate);
break;
int pageSize = 50;
Issues = await PaginatedList<Issue>.CreateAsync(issuesIQ.AsNoTracking(), pageIndex ?? 1, pageSize);
这会将日期范围设置为我最初加载页面时的最后 60 天(当没有提供参数时)并将它们转换为字符串(稍后会详细介绍),然后将这些字符串中存储的任何内容转换为Picker 使用的 DateTime 对象(如下所示)
<form asp-page="./Index" method="get">
<div class="form-actions no-color">
<p>
<div class="form-group">
<label asp-for="StartDate" class="control-label"></label>
<input asp-for="StartDate" class="form-control"/>
<span asp-validation-for="StartDate" class="text-danger"></span>
<label asp-for="EndDate" class="control-label"></label>
<input asp-for="EndDate" class="form-control"/>
<span asp-validation-for="EndDate" class="text-danger"></span>
</div>Find by Agent NT:
<input type="text" name="SearchString" value="@Model.CurrentFilter" />
<input type="submit" value="Search" class="btn btn-primary" /> |
<a asp-page="./Index">Back to full List</a>
</p>
</div>
</form>
从那里,我修改下一个和上一个按钮,以便在从一个页面导航到另一个页面时将选择器的值(在将其转换回字符串之后)传递给 get 方法。
<a asp-page="./Index"
asp-route-sortOrder="@Model.CurrentSort"
asp-route-pageIndex="@(Model.Issues.PageIndex - 1)"
asp-route-currentFilter="@Model.CurrentFilter"
asp-route-endDate="@TimeUtils.DateToString(Model.EndDate)"
asp-route-startDate="@TimeUtils.DateToString(Model.StartDate)"
class="btn btn-primary @prevDisabled">
Previous
</a>
<a asp-page="./Index"
asp-route-sortOrder="@Model.CurrentSort"
asp-route-pageIndex="@(Model.Issues.PageIndex + 1)"
asp-route-currentFilter="@Model.CurrentFilter"
asp-route-endDate="@TimeUtils.DateToString(Model.EndDate)"
asp-route-startDate="@TimeUtils.DateToString(Model.StartDate)"
class="btn btn-primary @nextDisabled">
Next
</a>
现在,解释为什么我使用字符串作为参数以及我遇到的问题。我注意到当我最初使用 DateTimes 作为参数时,我会将它们默认为 DateTime.MinValue,这并不是一件需要克服的大事,但是当我导航到下一页时,我的 URL 会出现一堆乱码和我的选择器值只会读取 mm/dd/yyyy。我做了一些阅读,发现 IIS 不喜欢使用 DateTime 中的某些分隔符,即使我使用了 [DataType(DataType.Date)] 注释。在这一点上,我阅读了一些关于 DateTime.Parse 和 DateTime.ToString 的文档,并在 TimeUtils 中制作了这些帮助函数
public static DateTime StringToDate(string datetime)
DateTime dt = DateTime.Parse(datetime);
return dt;
public static string DateToString(DateTime dt)
return dt.ToString("d");
这应该只是将 DateTime 转换为 2020 年 9 月 15 日这样的字符串,但是当我尝试从一个页面导航到另一个页面时,我在 URL 的末尾得到以下内容:
/Issues?pageIndex=3&endDate=9%2F14%2F2020&startDate=7%2F16%2F2020
总结一下,我是否走在正确的道路上,我是否只需要对 Parse 和 ToString 函数进行额外的自定义以从字符串中消除那些“/”?我正在考虑在 ToString 调用中使用 deculture 作为参数将其转换为“.”,但不确定是否会遇到类似问题。
【问题讨论】:
【参考方案1】:继续沿着我走的路走下去,但有一些警告,我仍然摸不着头脑。更新了 TimeUtils 辅助函数如下:
public static DateTime StringToDate(string datetime)
DateTime dt = DateTime.ParseExact(datetime,"yyyy-MM-dd",null);
return dt;
public static string DateToString(DateTime dt)
StringBuilder sb = new StringBuilder();
sb.Append(dt.Year);
sb.Append("-");
if (dt.Month < 10)
sb.Append("0");
sb.Append(dt.Month);
sb.Append("-");
if (dt.Day < 10)
sb.Append("0");
sb.Append(dt.Day);
return sb.ToString();
我最初采用“yyyyMMdd”格式的路线,但是当我尝试进行初始过滤(单击搜索)时,出现错误,表明 ParseExact 无法将“2020-09-16”转换为有效日期。我在 OnGet 中找不到任何地方发生了这种转换,并且发现 Append 发生了一些奇怪的事情,所以我将 ParseExact 更新为新格式。这工作得很好,直到我进入下一页,它实际上遵循了我的 DateToString 最初的编码(没有“-”)并且失败了。我更新了 DateToString 以包含“-”,现在一切都按预期工作。我的猜测是在过滤器中的 asp-for 选择上发生了某种对“yyyy-MM-dd”的隐式转换?不管它是否有效。
真棒。
【讨论】:
以上是关于在 Razor 页面中使用 DateTime 参数的主要内容,如果未能解决你的问题,请参考以下文章