Это происходит не потому, что id является DateTime, а потому, что id содержит символы косой черты (/
). Даже когда они кодируются, они декодируются и распознаются как символы косой черты в URL, тогда как кодировка действует в строке запроса, которая является частью после ?
в URL.
Следовательно, <a asp-action="Edit" asp-route-id="@item.CalendarDate">Edit</a>
генерирует URL-адрес, подобный /Model/Edit/2%2F3%2F2018%2012%3A00%3A00%20AM
, и фактически распознается как /Model/Edit/2/3/2018 12:00:00 AM
, и веб-приложение не может найти соответствия на карте маршрута.
С другой стороны, @Html.ActionLink("Edit", "Edit", new { CalendarDate = item.CalendarDate })
работал, потому что он генерирует URL, например Model/Edit?CalendarDate=03%2F03%2F2000%2001%3A00%3A00
. В этом случае он направляется на Model/Edit
, и контроллер получает значение CalendarDate.
Одним из решений является избавление от /{id?}
из следующей строки в Startup.cs.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
итак, будет выглядеть
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
});
затем вы увидите, что URL для ссылки редактирования будет сгенерирован как /Model/Edit?id=2%2F3%2F2018%2012%3A00%3A00%20AM
, где значение даты и времени находится в строке запроса и не декодируется, так что оно правильно передается в контроллер.
Если вы не хотите изменять функциональность маршрутизации, другое решение - изменить весь код, как показано ниже
<a asp-action="Edit" asp-route-id="@item.CalendarDate">Edit</a>
до
<a asp-action="Edit" asp-route-id="@item.CalendarDate.ToString("o")">Edit</a>
.ToString("o")
преобразует значение даты и времени в формат ISO 8601. В этом формате не используются символы косой черты, поэтому нет проблем с его отображением в URL.
К счастью, где изменить не так много. Только три места в Index.cshtml и одно в Details.cshtml. Вы можете заменить регулярное выражение (@[^.]+\.CalendarDate)
с заменой $1.ToString("o")
.
Таким способом вы можете уменьшить количество изменений, сравнивая с @Html.ActionLink("Edit", "Edit", new { CalendarDate = item.CalendarDate })
, потому что это решение не требует каких-либо изменений в контроллере.