简体   繁体   English

在 Razor 页面中使用日期时间参数

[英]Using DateTime Parameters in Razor Pages

Essentially I'm trying to build a date picker filter for my List page.本质上,我正在尝试为我的列表页面构建一个日期选择器过滤器。 I started by using some of the logic found in the search function detailed here: https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-3.1#add-paging我首先使用此处详述的搜索功能中的一些逻辑: https : //docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore- 3.1#添加分页

My Get method is structured like so:我的 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);
            
            
        }

This sets the date range to the last 60 days when I initially load the page(when no parameters are supplied) and converts them to strings(more on that in a moment), then converts whatever is stored in those strings into the DateTime objects used by the Picker(shown below)这将日期范围设置为我最初加载页面时的最后 60 天(当没有提供参数时)并将它们转换为字符串(稍后会详细介绍),然后将这些字符串中存储的任何内容转换为使用的 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>

From there, I modify the next and previous buttons to pass the value of the picker(after converting it back to a string) to the get method when navigating from page to page.从那里,我修改下一个和上一个按钮,以便在从一个页面导航到另一个页面时将选择器的值(在将其转换回字符串之后)传递给 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>

Now, to explain why I'm using strings for the parameters and where I'm stuck.现在,解释为什么我使用字符串作为参数以及我被卡住的地方。 I noticed when I was initially using DateTimes as the parameters I'd have them default to DateTime.MinValue, which wasn't a huge thing to overcome, but when I would navigate to the next page my URL would have a bunch of gibberish and my picker values would simply read mm/dd/yyyy.我注意到当我最初使用 DateTimes 作为参数时,我将它们默认为 DateTime.MinValue,这不是一个需要克服的大问题,但是当我导航到下一页时,我的 URL 会出现一堆乱码和我的选择器值只会读取 mm/dd/yyyy。 I did some reading and found IIS doesn't like to play well with some of the delimiters in DateTime, even with the [DataType(DataType.Date)] annotations I had in play.我做了一些阅读,发现 IIS 不喜欢使用 DateTime 中的某些分隔符,即使使用 [DataType(DataType.Date)] 注释也是如此。 At this point I read some documentation on DateTime.Parse and DateTime.ToString and made these helper functions in TimeUtils在这一点上,我阅读了一些关于 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");
        }

This should just convert the DateTime to a string like 9/15/2020, but when I try to navigate from page to page I'm getting the following at the end of my URL:这应该只是将 DateTime 转换为像 9/15/2020 这样的字符串,但是当我尝试从一个页面导航到另一个页面时,我在 URL 的末尾得到以下内容:

/Issues?pageIndex=3&endDate=9%2F14%2F2020&startDate=7%2F16%2F2020 /Issues?pageIndex=3&endDate=9%2F14%2F2020&startDate=7%2F16%2F2020

To boil all this down, am I on the right path here and do I just need to do additional customization on the Parse and ToString functions to eliminate those "/"s from the strings?将所有这些归结起来,我在这里是否走在正确的道路上,我是否只需要对 Parse 和 ToString 函数进行额外的自定义以从字符串中消除那些“/”? I'm considering using de culture as an argument in the ToString call to convert it to ".", but not sure if I'll run into similar problems.我正在考虑在 ToString 调用中使用 deculture 作为参数将其转换为“.”,但不确定是否会遇到类似的问题。

Figured it out by continuing down the path I was on, but with a few caveats I'm still scratching my head on.通过继续沿着我所走的道路来解决这个问题,但有一些警告我仍然在挠头。 Updated the TimeUtils helper functions as follows:更新了 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();
        }

I initially went the route of "yyyyMMdd" format, but when I tried to do the initial filter(clicking search) I had an error indicating the ParseExact couldn't convert "2020-09-16" to a valid date.我最初走的是“yyyyMMdd”格式的路线,但是当我尝试进行初始过滤器(单击搜索)时,出现错误,表明 ParseExact 无法将“2020-09-16”转换为有效日期。 I couldn't find anywhere in the OnGet this conversion was occurring and figured something wonky was happening with Append, so I updated the ParseExact to the new format.我在 OnGet 中找不到任何地方正在发生这种转换,并认为 Append 发生了一些奇怪的事情,所以我将 ParseExact 更新为新格式。 This worked fine until I went to the next page, which actually followed my DateToString as initially coded(without the "-"s) and failed.这工作正常,直到我进入下一页,该页面实际上遵循我最初编码的 DateToString(没有“-”)并且失败了。 I updated the DateToString to include the "-"s and now everything works as intended.我更新了 DateToString 以包含“-”,现在一切都按预期工作。 My guess is some kind of implicit conversion to "yyyy-MM-dd" was happening on the asp-for selection in the filter?我的猜测是在过滤器中的 asp-for 选择上发生了对“yyyy-MM-dd”的某种隐式转换? Regardless it works.不管它有效。

What a ride.多好啊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM