For some reason the dates that I enter in the date-type inputs of the form are not getting into the database. Instead, after all the different methods I researched and tried, to no avail, the dates default to 01/01/01, which I understand to be the defualt min value yes? And in the postgres database, the date fields show "-infinity". I can use pgadmin query tool to update the dates successfully, but when I try to create or edit a record from the form, the above occurs.
When I get to the ModelState.IsValid line in the debugger, it is showing the data I entered correctly in the other fields, but the date fields are showing 01/01/01.
I have been through the docs and other forum posts but none of the fixes I attempted worked. Any help would be greatly appreciated.
Here is the model
public class ToDo
{
[Key]
public int Id { get; set; }
public DateOnly CreateDate { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public DateOnly DueDate { get; set; }
public bool Complete { get; set; }
}
... the post
public async Task<IActionResult> OnPost()
{
if (!ModelState.IsValid)
{
var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));
}
if (ModelState.IsValid)
{
await _db.Todo.AddAsync(Todo);
await _db.SaveChangesAsync();
TempData["success"] = "ToDo created successfully.";
return RedirectToPage("Index");
}
return Page();
}
... and the form
<form method="post">
<input hidden asp-for="Todo.Id" />
<div class="p-3 mt-4">
<div class="row pb-2">
<h2 class="text-primary pl-3">Create ToDo</h2>
<hr />
</div>
<div asp-validation-summary="All"></div>
<div class="mb-3">
<label asp-for="@Model.Todo.CreateDate"></label>
<input asp-for="@Model.Todo.CreateDate" class="form-control" type="date"/>
<span asp-validation-for="Todo.CreateDate" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="@Model.Todo.Name"></label>
<input asp-for="@Model.Todo.Name" class="form-control" />
<span asp-validation-for="Todo.Name" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="@Model.Todo.Description"></label>
<input asp-for="@Model.Todo.Description" class="form-control" />
<span asp-validation-for="Todo.Description" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="@Model.Todo.DueDate"></label>
<input asp-for="@Model.Todo.DueDate" class="form-control" type="date"/>
<span asp-validation-for="Todo.DueDate" class="text-danger"></span>
</div>
<div class="form-check m-4">
<input asp-for="@Model.Todo.Complete" class="form-check-input" type="checkbox"/>
<label class="form-check-label ms-3" asp-for="@Model.Todo.Complete">
Complete
</label>
</div>
<button type="submit" class="btn btn-outline-primary rounded-pill" style="width:150px;">Update</button>
<a asp-page="Index" class="btn btn-outline-secondary rounded-pill text-white" style="width:150px;">Back To List</a>
</div>
</form>
You are using the new DateOnly
type. The ASP.NET Core model binder does not support binding to DateOnly
at the moment (https://github.com/dotnet/aspnetcore/issues/34591). Until .NET 7, you can use a DateTime
type and data annotations to control the input type that gets rendered (https://www.learnrazorpages.com/razor-pages/forms/dates-and-times):
[DataType(DataType.Date)]
public DateTime CreateDate { get; set; }
Alternatively, you can extract the value from Request.Form
yourself and assign it to the relevant property:
if(DateTime.TryParse(Request.Form["Todo.CreateDate"].ToString(), out var created))
{
Todo.CreateDate = DateOnly.FromDateTime(created);
}
else
{
ModelState.AddModelError("Todo.CreateDate", "A created date must be a date");
}