Datapicker for nullable DateTime binds incorrectly - c#

I have this problem, where i have 2 properties in my project entity:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "dd/MM/yyyy", ApplyFormatInEditMode = true)]
public DateTime? StartDate { get; set; }
[DisplayFormat(DataFormatString = "dd/MM/yyyy", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public DateTime EndDate { get; set; }
In my view i have the following code.
<div class="control-group">
<label class="control-label" for="prependedInput">#Resources.Project.StartDate</label>
<div class="controls">
<div class="input-prepend">
<input type="text" name="StartDate" class="input-small datepicker" value="#DateTime.Now.ToDateFormat()" />
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="prependedInput">#Resources.Project.EndDate</label>
<div class="controls">
<div class="input-prepend">
<input type="text" name="EndDate" class="input-small datepicker" value="#DateTime.Now.ToDateFormat()" />
</div>
</div>
</div>
In my controller i am trying to create a new object but the ModelState.IsValid always returns false because the StartDate has a null value.
public virtual ActionResult Create(Project model)
{
if (ModelState.IsValid)
{
Repository.Project.Add(model);
return RedirectToAction(MVC.Project.Index());
}
return View(model);
}
How can i solve this problem and set the value of my nullable StartDate property to the date selected with datepicker ?

DisplayFormat attribute have no effect on DateTime? when binding data. Because of this default data binder expects the date to be in standard format f.e. YYYY-MM-dd.
If you want to bind datetime in diffent format use custom data binder. You can find solution here:
http://blog.greatrexpectations.com/2013/01/10/custom-date-formats-and-the-mvc-model-binder/
It should work perfectly for your problem.

Related

Datetime from API , Create/post to API

I got two different projects, one API and one for the web(front).
I Can create a course through my API but when i try to post from my front-end i got this error,
FormatException: Input string was not in a correct format.
And it complains on this one,
<span asp-validation-for="CourseTitle" class="text-danger"></span>
</div>
<div class="col-2">
<label asp-for="CourseStart" class="control-label pt-2" style="font-size:20px;"></label>
</div>
<div class="col-10 pb-3">
<input asp-for="CourseStart" class="form-control" />
<span asp-validation-for="CourseStart" class="text-danger"></span>
</div>
<div class="col-2">
<label asp-for="CourseEnd" class="control-label pt-2" style="font-size:20px;"></label>
</div>
<div class="col-10 pb-3">
Somehow my CourseStart doesnt work, and my class looks like this,
[Key]
public int CourseId { get; set; }
[Required]
public string CourseTitle { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime CourseStart { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime CourseEnd { get; set; }
The problem i think i got is that when i save a course through the API i got Date like this,
"courseStart": "2022-12-15T00:00:00"
So i think its expecting T00:00:00 somehow? What do u think? I cant find anything on google....
I made it work, what i did was,
changed my class to this,
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime CourseStart { get; set; }
after that, inside my html file, i put in this,
<div class="col-2">
<label asp-for="CourseStart" class="control-label pt-2" style="font-size:20px;"></label>
</div>
<div class="col-10 pb-3">
<input asp-for="CourseStart" type="date" class="form-control" />
<span asp-validation-for="CourseStart" class="text-danger"></span>
</div>
problem was that, through html helper, it saved it in this format, yyyy-MM-dd, so i had to change it. U can probably customize it but its to complicated for me :)

Razor Pages - DateOnly and TimeOnly Bind to Html Input Controls?

how can u bind dateonly and timeonly fields to html controls such ass date picker and time picker? i am using Mariadb as rdbms , I want to show to the end user date and time picker inputs, so far the date and time picker wont work properly.
<form method="post">
<input hidden asp-for="Period.Periodid" />
<div class="border p-3 mt-4">
<div class="row mb-3">
<h4 class=" pl-3">Επεξεργασία Επαφής</h4>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="mb-3">
<label asp-for="Period.StartDate">Ημερομηνία Έναρξης</label>
<input type="date" asp-for="Period.StartDate" class="form-control" />
<span asp-validation-for="Period.StartDate" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="Period.EndDate">Ημερομηνία Λήξης</label>
<input type="date" asp-for="Period.EndDate" class="form-control" />
<span asp-validation-for="Period.EndDate" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="Period.StartTime">Ώρα Έναρξης</label>
<input type="time" asp-for="Period.StartTime" class="form-control" />
<span asp-validation-for="Period.StartTime" class="text-danger"></span>
</div>
<div class="mb-3">
<label asp-for="Period.EndTime">Ώρα Λήξης</label>
<input type="time" asp-for="Period.EndTime" class="form-control" />
<span asp-validation-for="Period.EndTime" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary" style="width:150px;">Ενημέρωση</button>
<a asp-page="Index" class="btn btn-secondary" style="width:150px;">Λίστα</a>
</div>
model
public class Period
{
public int Periodid { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateOnly StartDate { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateOnly EndDate { get; set; }
[Required]
[DataType(DataType.Time)]
public TimeOnly StartTime { get; set; }
[Required]
[DataType(DataType.Time)]
public TimeOnly EndTime { get; set; }
}
dateonly and timeonly are not supported yet for form binding (they will support it in dotnet 7)
see related post and solutions
stackoverflow related issue

Problem with inputfield DateTime and TimeSpan

I'm having trouble with some ASP/C# inputfields. Here is a screencapture of what I have:
It is a inputfield for movies in a cinema. StartAt is the startdate of a timetable, EndAt is the enddate of the timetable and the Time represents the daily time within the two dates that the movie is playing daily.
Problem is I'm European and normal pattern would be dd-mm-yyyy for us. I cannot get that done. The bigger problem is the Timespan. That should be HH:mm (24h clock) and not HH:mm:ss.
Here is my View-code:
<div class="form-group">
<label asp-for="StartAt" class="control-label"></label>
<input asp-for="StartAt" class="form-control" />
<span asp-validation-for="StartAt" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EndAt" class="control-label"></label>
<input asp-for="EndAt" class="form-control" />
<span asp-validation-for="EndAt" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Time" class="control-label"></label>
<input asp-for="Time" class="form-control" />
<span asp-validation-for="Time" class="text-danger"></span>
</div>
And here is my model:
public class MovieRuntime
{
public int Id { get; set; }
public int MovieId { get; set; }
public int HallId { get; set; }
[DataType(DataType.Date)]
[Column(TypeName = "Date")]
public DateTime StartAt { get; set; }
DataType(DataType.Date)]
[Column(TypeName = "Date")]
public DateTime EndAt { get; set; }
[DataType(DataType.Time)]
[Column(TypeName = "Time")]
public TimeSpan Time { get; set; }
[ForeignKey("MovieId")]
public virtual Movie Movie { get; set; } = null!;
[ForeignKey("HallId")]
public virtual Hall Hall { get; set; } = null!;
}
I tried to use DisplayFormat in the model, but this didn't help:
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
What do I miss here?
You can use asp-formatting to specify the format of the date and time.
asp-format="{0:dd.MM.yyyy}"
<div class="form-group">
<label asp-for="StartAt" class="control-label"></label>
<input asp-for="StartAt" asp-format="{0:dd.MM.yyyy}" type="date" class="form-control" />
<span asp-validation-for="StartAt" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EndAt" class="control-label"></label>
<input asp-for="EndAt" asp-format="{0:dd.MM.yyyy}" type="date" class="form-control" />
<span asp-validation-for="EndAt" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Time" class="control-label"></label>
<input asp-for="Time" asp-format="{0:HH:mm}" type="time" class="form-control" />
<span asp-validation-for="Time" class="text-danger"></span>
</div>
Html date input isn't offically possible to format change. Pure element always show based on browser culture.
You should use 3rd library (like bootstrap datepicker, jquery datepicker) or you can hack with css, js (ex : https://stackoverflow.com/a/31162426/14671235)
I made a workaround for the biggest problem, the TimeSpan. I changed the input-field to a textbox:
<input type="text" class="form-control" placeholder="i.e 12:00" name="time" onchange="validateHhMm(this)" required=""/>
I added a javascript regex-checker which changes the bg-color of the textfield red and disables the button when it's not the right expression:
<script>
function validateHhMm(inputField)
{
var isValid = /^([0-1]?[0-9]|2[0-4]):([0-5][0-9])(:[0-5][0-9])?$/.test(inputField.value);
if (isValid) {
inputField.style.backgroundColor = '#bfa';
document.getElementById('addButton').disabled = false;
} else {
inputField.style.backgroundColor = '#fba';
document.getElementById('addButton').disabled = true;
}
return isValid;
}
</script>
Output is now like this:
For the Pattern problem, the problem was that my browser was on US-settings. That is why I got the US pattern. I changed it to Dutch and this was the output:

'The string 'FromDate' was not recognized as a valid DateTime. There is an unknown word starting at index '0'. during CustomValidationAttribute

I am making a custom validation attribute for the first time. It is for the TillDate to be greater or equal to the FromDate. I am getting the following error for the FromDate
System.FormatException: 'The string 'FromDate' was not recognized as a valid DateTime. There is an unknown word starting at index '0'.'
I am not sure about why this error is coming, whether it is because of something wrong in the Validation Attribute or something else.
Any help will be appreciated. Thank you!!
This is the customAttribute class
public class EndDateGreaterValidationAttribute : ValidationAttribute
{
public string _FromDate { get; private set; }
public EndDateGreaterValidationAttribute(string FromDate)
{
_FromDate = FromDate;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
DateTime _EndDat = DateTime.Parse(value.ToString());
DateTime? _fromDate = DateTime.Parse(_FromDate);
int cmp = _EndDat.CompareTo(_fromDate);
if (cmp > 0)
{
// date1 is greater means date1 is comes after date2
return ValidationResult.Success;
}
else if (cmp < 0)
{
// date2 is greater means date1 is comes after date1
return new ValidationResult(ErrorMessage);
}
else
{
// date1 is same as date2
return ValidationResult.Success;
}
}
}
This is the View model to the properties of which the attribute is applied
public class ApplyLeaveViewModel : ApplicationUser
{
[DisplayName("Date Applied")]
public DateTime DateApplied { get; set; }
public ApplyLeaveViewModel()
{
DateApplied = DateTime.Now;
}
[DisplayName("From Date")]
public DateTime FromDate { get; set; }
[DisplayName("Till Date")]
[EndDateGreaterValidation ( "FromDate", ErrorMessage = "End date must be greater than start date")]
public DateTime TillDate { get; set; }
}
This is the View
<div class="form-row mt-3">
<div class="form-group col-6">
#*<label class=" col-form-label small form-text">Date Applied On:</label>*#
#*<label asp-for="#Model.DateApplied" class="col-form-label small form-text">Date Applied:</label>*#
<div class="col">
<input type="text" hidden asp-for="#Model.DateApplied">
</div>
</div>
</div>
<div class="form-label mt-3">
<label class="col-form-label small form-text">Date(s) Requested For:</label>
</div>
<div class="form-row">
<div class="form-group col-md-6 ">
<label asp-for="FromDate" class="col-auto col-form-label small form-text">From Date:</label>
<div class="col">
<input asp-for="FromDate" type="date" class="form-control datepicker" />
<span asp-validation-for="FromDate" class="text-danger"></span>
#Html.ValidationMessageFor(model => model.FromDate)
</div>
</div>
<div class="form-group col-md-6 ">
<label asp-for="TillDate" class="col-auto col-form-label small form- text">Till Date:</label>
<div class="col">
<input asp-for="TillDate" type="date" class="form-control datepicker" />
<span asp-validation-for="TillDate" class="text-danger"></span>
#Html.ValidationMessageFor(m => m.TillDate)
</div>
</div>
</div>

Format date in a View in ASP.NET Core MVC

How can I make the date format to be "dd.MM.yyyy" because whatever I do it is always "MM/dd/yyyy"
View part:
<div class="col-md-6 col-xs-6 pull-left">
<label asp-for="#Model.RequestRegistrationDateFrom"></label>
<div class="input-group date">
<input type="text" asp-for="#Model.RequestRegistrationDateFrom" class="form-control js-datepicker pull-left" />
<div class="input-group-append">
<span class="input-group-text calendar-fa"></span>
</div>
</div>
</div>
Model property:
[BindProperty(SupportsGet = true)]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "dd.MM.yyyy")]
[Display(Name = "Date from", ResourceType = typeof(string))]
public DateTime? RequestRegistrationDateFrom { get; set; }
This should work:
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
I have heard such case as you are experiencing. Unfortunately, I haven't got it myself, and haven't got a chance to dig into what's actually wrong behind DisplayFormat attribute.
In that case, passing formatted string to value attribute worked.
<input type="text" asp-for="RequestRegistrationDateFrom" value="#Model.RequestRegistrationDateFrom.ToString("dd.MM.yyyy")" class="form-control js-datepicker pull-left" />
Try it for now. Hopefully, it would work in your case too.
If you could post a solution here when you figure out the problem behind, that'll be awesome. I'm interested in it.
It's very simple bro, just do the following:
[DataType(DataType.Date)]
public DateTime Date { get; set; } = DateTime.Today;
In your model:
[Column(TypeName = "Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime start_date { get; set; }
In your view:
<td>#item.start_date.ToString("dd/MM/yyyy")</td>

Categories

Resources