#c# #datetime #razor-pages #asp.net-core-3.1
#c# #datetime #страницы razor #asp.net-core-3.1
Вопрос:
По сути, я пытаюсь создать фильтр выбора даты для моей страницы списка. Я начал с использования некоторой логики, найденной в функции поиска, подробно описанной здесь: https://learn.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 дней, когда я изначально загружаю страницу (когда параметры не указаны), и преобразует их в строки (подробнее об этом чуть позже), затем преобразует все, что хранится в этих строках, в объекты 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>
Оттуда я изменяю кнопки next и previous, чтобы передавать значение средства выбора (после преобразования его обратно в строку) методу 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-адрес будет содержать кучу тарабарщины, а мои значения выбора будут просто читать мм / дд / гггг. Я немного почитал и обнаружил, что IIS не очень хорошо работает с некоторыми разделителями в DateTime, даже с аннотациями [DataType (DataType.Date)], которые у меня были в игре. На данный момент я прочитал некоторую документацию по DateTime.Синтаксический анализ и 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 в строку типа 9/15/2020, но когда я пытаюсь перейти со страницы на страницу, я получаю следующее в конце моего URL:
/ Проблемы?pageIndex=3amp;EndDate = 9/14/2020amp; StartDate = 7/16/2020
Чтобы свести все это к минимуму, я на правильном пути здесь, и мне просто нужно выполнить дополнительную настройку функций Parse и toString, чтобы исключить эти «/» из строк? Я рассматриваю возможность использования de culture в качестве аргумента в вызове toString для преобразования его в «.», но не уверен, что столкнусь с подобными проблемами.
Ответ №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();
}
Изначально я выбрал формат «ГГГГМДД», но когда я попытался выполнить начальный фильтр (нажав поиск), у меня возникла ошибка, указывающая, что ParseExact не смог преобразовать «2020-09-16» в действительную дату. Я нигде не мог найти в OnGet, где происходило это преобразование, и подумал, что с Append происходит что-то неладное, поэтому я обновил ParseExact до нового формата. Это работало нормально, пока я не перешел на следующую страницу, которая фактически следовала за моей DateToString в исходном кодировании (без знаков «-«) и завершилась неудачей. Я обновил DateToString, включив в него символы «-«, и теперь все работает так, как задумано. Я предполагаю, что какое-то неявное преобразование в «гггг-ММ-дд» происходило на asp-для выбора в фильтре? Независимо от того, работает ли это.
Какая поездка.