Snippet from Model
[Display(Name = "Updated Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public Nullable<DateTime> updatedAt { get; set; }
Snippet from Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(NcRecordClass model)
{
if (ModelState.IsValid)
{
var NcRecord = new NcRecordClass()
{
Id = model.Id,
updatedAt = model.updatedAt,
note = model.note
};
db.Entry(NcRecord).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Edit", new { id = model.Id, update = true });
}
return View(model);
}
Snippet from View
#Html.TextBoxFor(model => model.updatedAt, #"{0:dd\/MM\/yyyy}", new { #class = "form-control" })
When I try to update this column using the value '25/11/2020' , this warning will come out
The value '25/11/2020' is not valid for Updated Date.
I want to use the dd/MM/yyyy format in the application.
By the way, I use Postgres DB for this project (Datatype for updatedAt is 'timestamp without time zone'.
I have a similar project using the same code, the only difference is that project is using MSSQL server. And that project have no problem like this.
The [DisplatFormat] attribute is only respected when using DisplayFor() or EditorFor(). To format a value using TextBoxFor(), you need to use an overload that accepts a format string:
#Html.TextBoxFor(m => m.updatedAt,"{0:dd/MM/yyyy}", new { type = "date" , class = "form-control"})
Answer by Sergey partly helped. When I put the type = "date", the textbox become a datepicker which was even better, and I can update the date. But the problem was after I update, the value shown on the textbox was "dd/mm/yyyy" literally. Then I found out that The date of an html input element of type date must be formatted in respect to ISO8601, which is: yyyy-MM-dd Link Here .
So finally, the code that work is this:
#Html.TextBoxFor(model => model.updatedAt, #"{0:yyyy-MM-dd}", new { #class = "form-control", type = "date" })
Related
This is my model's date property:
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy.mm.dd}")]
[Required(ErrorMessage = "You need to fill this")]
[DataType(DataType.DateTime, ErrorMessage = "Type proper date")]
[Display(Name = "Weight Date")]
public DateTime? WeightDate { get; set; }
This is how I render bootstrap's datepicker
#Html.EditorFor(x => x.WeightDate, new { htmlAttributes = new { #id="WeightDate" #class = "form-control datepicker", #required = "required" }})
#Html.ValidationMessageFor(m => m.WeightDate, "", new { #class = "text-danger" })
Validation seems to working (I can see "You need to fill this" when entering empty datepicker value). The problem is that I can see other messages, which I would don't want to see (or at least change their messages):
When I enter invalid data, I am getting error (from client side):
The field Weight date must be a date.
When I submit invalid data, I am getting error (from server side):
The value '202441.02.03' is not valid for Weight date.
How can I change those messages?
I have tried different approach to make a dateTime text box, this is the one that works, but the problem is I cannot set a default date.
Here's what I am working on:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)]
Then I set the date today, DateTime.Now like this model.NotifyDate = DateTime.Now;
It doesn't set the date. However, if I remove [DataType(DataType.Date)] from the model I will get:
I will get the date, but the calendar is gone. What's the problem? Or am I using the datepicker wrong?
Here's my view:
#Html.EditorFor(m => m.NotifyDate, new { htmlAttributes = new { #class = "form-control input-sm" } })
You were on the right track! Defaults such as this should be set in the ViewModel
(as it appears you're doing w/ model.NotifyDate = DateTime.Now;)
The problem here appears to be that the browser is expecting the value for the generated html input element to be formatted differently -- namely, yyyy-MM-dd vs yyyy/MM/dd.
(note the use of - vs /)
In order for the browser to correctly display the date, the value must be formatted as 2019-09-23.
ex:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
Here is a great answer to a similar question that should shed some more light on what's going on as well.
You should try this datepicker in js.
$('.date').datepicker({
format: "dd.mm.yyyy",
weekStart: 1,
clearBtn: true,
todayBtn: "linked",
language: "tr",
startDate: new Date(),
autoclose: true
});
Since Browser is expecting the value for the generated HTML input, you either need to provide value with client-side javascript (or client-side datepicker) or bind the value to model.
You can bind the value to model and pass to view from the controller as follows.
public async Task<ActionResult> Create()
{
var dateInfo = new DateInfo()
{
StartDate = DateTime.Now
};
return View(dateInfo);
}
Or you can assign value from client side. jQuery UI is simple and easy to implement. You can Visit .
I am working on a Inventory project but I can't save Datetime datatypes like dd/MM/yyyy into Database. I know Database uses yyyy-MM-dd as standard Datetime but it also accepts MM-dd-yyyy(I think compiler converts it to yyyy-MM-dd).
This is what I have:
Model
[Required(ErrorMessage = "*Ingrese una fecha.")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
[Display(Name ="FECHA")]
public DateTime Fecha { get; set; }
View
#Html.LabelFor(m => m.Entrada.Fecha, new { #class = "control-label" })
#Html.TextBoxFor(m => m.Entrada.Fecha, "{0:dd/MM/yyyy}", new { #class = "form-control datepicker" })
#Html.ValidationMessageFor(m => m.Entrada.InventarioId, "", new { #class = "text-danger" })
When clicking the submit button it doesn't add to database, but when I write any Datetime with mm/dd/yyyy(For example 08/21/2019) type, it submits to database. I can't find solution on the internet.
You can try the following
bool parsed = false;
DateTime outDate;
parsed = DateTime.TryParseExact(inputDate, "dd-MM-
yyyy", CultureInfo.CurrentCulture, DateTimeStyles.None,
out outDate);
if(parsed)
{
usr.DogumTarihi = outDate.ToString("yyyy-MM-dd");
}
else
{
// Invalid date has been passed
}
If you are working with DateTime and not string, the way the database stores displays the date will be yyyy-MM-dd. Sometimes if the date is not sent properly and seeing as your DateTime field is not nullable, it send the value 01/01/0001 (annoying right) so this is what i do...
In the model,
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true, NullDisplayText = "NULL")]
In the view, i have
#Html.TextBoxFor(m => m.Entrada.Fecha, new { #class = "form-control datepicker", placeholder = "Enter Date", id = "Date", autocomplete = "off" })
and in the date picker js options,
$(document).ready(function () {
$('.datepicker').datepicker({
dateFormat: "dd/mm/yy"
});
});
This way, date is stored how database is configured and it is however displayed in the format dd/MM/yyyy. I know it does not answer the question of storing the date in the format you want but this way, you can DISPLAY the date in the format you want, both during submission, editing and displaying it.
Edit 1
Just to Clarify a couple of points,
The datetime picker/script appears to be working fine, the times and dates are selectable and fill the textbox with the correct values as expected.
The issue occurs when a time/date is manually entered into the textbox by the user and an invalid time is entered (i.e. "78/5/2017 12:00" or "12/5/2017 12:62")
I've updated a typo in the code, the error is still occurring with the corrected code.
I have my fingers crossed I'm missing something obvious because this makes no sense to me. Any help you can offer would be much appreciated. I have included my code at the end of the question.
The Problem
I have two DateTime fields which are included in a form on a page in my application: StartTime and EndTime.
Both of the fields are setup and put onto the page using (what I believe to be) identical code.
The StartTime field works perfectly, only excepting valid times as input and displaying an error for nonsensical times such as 28:30 or 17:67 until the User corrects it.
The EndTime field however does not validate correctly. Bad inputs are switched back to the current Time/Date before being passed back to the controller, the controller never even sees the bad values meaning I can't catch it and return an error at that point.
If nonsensical values are given in both fields then the submission is prevented and both fields show a validation error which suggests that the EndTime validation does work, it just doesn't prevent form submission.
My Efforts
As I have one working field I have attempted to use that to correct the error. However I hit a stumbling block in realising that there are no differences between the two. Deciding that I must have missed something I switched the variable names round so that the StartTime would be using the EndTime code and vice versa, I did this in each of the sections below one by one hoping to find a point where the field which was working swapped. That, however, never happened. Even once the entirety of their code was switched over it was still found to be the EndTime variable/field which was broken and the StartTime variable/field which was working.
My Research
Despite spending nearly a week with this bug now I have been unable to find any similar problems online and am at a complete stumbling block as to where to go or what to try now. I have tried looking for issues caused by DateTime calendar pickers as well as validation errors in general but can't find anything of use to this situation.
This is one of the last bugs to fix before the project is completed and so any help or even ideas you can offer would be amazing.
The Code
I have included everything I could think to here that interacts with the fields in question. If I have missed anything or you need more info please let me know.
The Entity Model
I have the following two DateTime fields in my Record Entity
public partial class Record
{
// Other entity fields
// ....
// ...
// ..
[DisplayName("Start Time")]
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:g}", ApplyFormatInEditMode = true)]
public DateTime StartTime { get; set; }
[DisplayName("End Time")]
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:g}", ApplyFormatInEditMode = true)]
public DateTime EndTime { get; set; }
// and in the constructor
public Record()
{
// initialise the DateTime fields with the current DateTime,
// adjusted for daylight savings
BaseController b = new BaseController();
StartTime = b.TimeNow();
EndTime = b.TimeNow();
}
}
For the sake of completion this is the TimeNow() function's code:
public DateTime TimeNow()
{
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
DateTime t = DateTime.Now;
if (tz.IsDaylightSavingTime(t))
t = t.AddHours(1);
return t;
}
The ViewModel
The Record entity is then included into a ViewModel as follows:
public class Home_UserAddRecord
{
[DisplayName("Record")]
public Record record { get; set; }
// Other ViewModel fields
// ....
// ...
// ..
// and the blank constructor:
public Home_UserAddRecord()
{
record = new Record();
Error = false;
ErrorMessage = string.Empty;
}
}
The CSHTML Form
They are then included into a form on the page like so:
#using (Html.BeginForm())
{
<div class="form-horizontal">
<div class="form-group col-md-12">
#Html.LabelFor(model => model.record.StartTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-5">
#Html.EditorFor(model => model.record.StartTime, new { htmlAttributes = new { #Value = Model.record.StartTime.ToString("dd/MM/yyyy HH:mm"), #class = "form-control", #id = "StartDate" } })
#Html.ValidationMessageFor(model => model.record.StartTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group col-md-12">
#Html.LabelFor(model => model.record.EndTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-5">
#Html.EditorFor(model => model.record.EndTime, new{ htmlAttributes = new{ #Value = Model.record.EndTime.ToString("dd/MM/yyyy HH:mm"), #class = "form-control", #id = "EndDate" } })
#Html.ValidationMessageFor(model => model.record.EndTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
An Attached Script
And then finally they have a script applied to them to allow the use of a calendar picker on each input. The script looks like this:
#section Scripts{
<script>
var Start = new dhtmlXCalendarObject("StartDate");
Start.setDateFormat("%d/%m/%Y %H:%i");
Start.showToday();
Start.attachEvent("onTimeChange", function (d) {
var DateText = Start.getDate(true)
document.getElementById("StartDate").value = DateText;
});
var End = new dhtmlXCalendarObject("EndDate");
End.setDateFormat("%d/%m/%Y %H:%i");
End.showToday();
End.attachEvent("onTimeChange", function (d) {
var DateText = End.getDate(true)
document.getElementById("EndDate").value = DateText;
});
</script>
}
Perhaps a suggestion is to use DateTime.TryParseExact method, which will validate the "String" representation of the date using your desired format, and will return an error when the string does not comply to your specified format. Here is code, note dateFormats are based on Australian Standard dates. You can of course add hours and minutes to this too.
Note parsedDate is a DateTime format. Usage of below is:
public void test(){
DateTime ParsedDate;
string SomeDate = "12-May-2017";
if(parseDate(SomeDate, out ParsedDate))
{
// Date was parsed successfully, you can now used ParsedDate, e.g.
Customer.Orders[0].DateRequired = ParsedDate;
}
else
{
// Throw an error
}
}
And the method declaration. Use either in static class, or directly in your class.
public static bool parseDate(string theDate, out DateTime parsedDate)
{
string[] dateFormats = { "d-M-yy", "d-MMM-yy", "d-MMM-yyyy", "d-M-yyyy", "d/M/yy", "d/M/yyyy", "yyyy-mm-dd" };
bool result = DateTime.TryParseExact(
theDate,
dateFormats,
new CultureInfo("en-AU"),
DateTimeStyles.None, out parsedDate);
return result;
} //Convert string-based date to DateTime. Uses a variety of parse templates
I once faced a similar issue where view was submitting the model even if validation failed. I happened to be not using ModelState.IsValid() in the controller action. Do check if this helps.
I am trying to populate #Html.EditorFor helper. I have created a view model with the below property
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yy}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
and my helper is set up as below (a)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought, new { #type = "date" })
I have also tried (b)
#Html.ValidationMessageFor(m => m.YearBought)
#Html.EditorFor(model => model.YearBought.Value.Date)
Using the above format (a) nothing is displayed. Using the above format (b) 12/05/2014 00:00:00 is displayed in textbox format.
I am trying to achieve a datepicker format without a time displayed
I have reviewed several other questions but cant see what i've done different.
When I look in my database, the value is save as 2014-05-12 and when I am saving the value the EditorFor helper generates the required input facility
questions reviewed
first second third....the list goes on
EDIT
just opened the console in chrome dev tools and so this message
The specified value "12/05/14" does not conform to the required format, "yyyy-MM-dd"
I thought DisplayFormat(DataFormatString = "{0:dd/MM/yy}" was defining how to display my date?
You need to use the ISO format when using type="date"
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
This will display the date in the browsers culture.
Note there is no need to add #type = "date". The EditorFor() method will add that because of the DataType attribute. Note also that type="date" is only supported in Chrome (FireFox and IE will just generate a normal textbox)
If you do want to display the format dd/MM/yyyy in a standard textbox then you can use
#Html.TextBoxFor(m => m.YearBought, "{0:dd/MM/yyyy}")
As it says in Stephen's answer, you have to make your formats match between the tags in your model to what is shown in the View, and it should be of the yyyy-MM-dd (ISO) format, regardless of how you actually want to display the date:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// .... your namespace .... your class....
[DisplayName("Year Bought")]
[DataType(DataType.Date, ErrorMessage="Date only")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? YearBought { get; set; }
And he's right, because we have [DataType(DataType.Date)], we don't need #type = date in our HtmlAttributes on the View.
Where my answer differs from his is how to actually apply the value from the Model to the control on the View. Since YearBought is a Nullable<DateTime>, we have to set it with its value a certain way, using .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought.Value.Date.ToString("yyyy-MM-dd") } })
Paying close attention to set the .ToString("yyyy-MM-dd"). It's not going to display in the box like that, though - at least for me - probably because my U.S. Regional settings on my computer take over and display it as MM/dd/yyyy regardless. This might confuse some, but it's better to just "do" and not worry about it.
If YearBought was just a straight DateTime instead of a DateTime?, it would be without the .Value:
#Html.EditorFor(model => model.YearBought,
new { htmlAttributes = new { #class = "form-control datepicker",
#Value = Model.YearBought != null ?
Model.YearBought.Value.Date.ToString("yyyy-MM-dd") : null } })
I would make your view model's YearBought property a String for the easiest manipulation. The server can format the date, it can do the parsing on postback, and you can still use the DataType.Date data annotation for jQuery validation. This also ensures that the display value will be exactly what you want prior to being submitted to the view.
Alternative to the HTML type attribute, you can use an EditorTemplate in MVC to put the markup, CSS, and JS needed to render a custom editor for a known C# datatype like DateTime.
Here is a walkthrough for creating a custom 'EditorTemplate' in MVC (although not for a Date data type, but concept is the same)