Validating dates in aspnet mvc - asp.net-mvc

I have my ViewModel on which I've defined my properties; one of them is a DateTime field defined as:
[DisplayName("Data")]
[DataType(DataType.Date)]
[Required(ErrorMessage="Selezionare una data")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}" )]
public DateTime? DtNews { get;set; }
When I submit the form I always receive the error msg "The value '13/07/2011' is not valid for DtNews" because the system swaps days and months ... I need to have dd/mm/yyyy format.

You could set the culture in your web.config to some culture for which the date format is dd/MM/yyyy. For example that's the case with it-IT:
<globalization culture="it-IT" uiCulture="it-IT"/>
By default the culture is set to auto. This means that ASP.NET uses the browser settings in order to deduce the culture of the client. So if the browser is configured to use en-US, then the format for dates will be MM/dd/yyyy.
Another possibility is to set the format for the current thread culture:
var dtfi = (DateTimeFormatInfo)Thread.CurrentThread.CurrentCulture.DateTimeFormat.Clone();
dtfi.ShortDatePattern = "dd/MM/yyyy";
dtfi.DateSeparator = "/";
Thread.CurrentThread.CurrentCulture.DateTimeFormat = dtfi;
Thread.CurrentThread.CurrentUICulture.DateTimeFormat = dtfi;

Related

How to Format Numbers Globally

I am using ASP.NET MVC 5 and I have many classes with decimal fields.
I know that I can use:
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
public decimal MyDecimal { get; set; }
in order to format the display of the number, but this means entering the attribute for every field.
I need a method to format these numbers globally.

ASP.NET MVC USD Currency Validation

In my ViewModel, I have the following System.ComponentModel.DataAnnotations on a property that contains USD currency:
[DisplayFormat(DataFormatString = "{0:C2}")]
[Range(0.01, 100000, ErrorMessage = "Payment amount is required between .01 and $100,000.")]
[DataType(DataType.Currency)]
[DisplayName("Payment Amount")]
public Double PrinAmount { get; set; } = 0.00;
When I enter a value of $10.005, I get the following validation model error from the ModelState.IsValid check:
The value '$10.005' is not valid for Payment Amount.
When I enter a value 10.005, the ModelState.IsValid is equal to true.
What do I need to do to modified the validation to capture both formats as invalid?
You can use Regular Expression;
[RegularExpression(#"^\d+\.\d{0,2}$")]
the DataAnnotations above ensures 2 digits.

How to give a date Format to the sting parameter in query string? [duplicate]

I have to convert string in mm/dd/yyyy format to datetime variable but it should remain in mm/dd/yyyy format.
string strDate = DateTime.Now.ToString("MM/dd/yyyy");
Please help.
You are looking for the DateTime.Parse() method (MSDN Article)
So you can do:
var dateTime = DateTime.Parse("01/01/2001");
Which will give you a DateTime typed object.
If you need to specify which date format you want to use, you would use DateTime.ParseExact (MSDN Article)
Which you would use in a situation like this (Where you are using a British style date format):
string[] formats= { "dd/MM/yyyy" }
var dateTime = DateTime.ParseExact("01/01/2001", formats, new CultureInfo("en-US"), DateTimeStyles.None);
You need an uppercase M for the month part.
string strDate = DateTime.Now.ToString("MM/dd/yyyy");
Lowercase m is for outputting (and parsing) a minute (such as h:mm).
e.g. a full date time string might look like this:
string strDate = DateTime.Now.ToString("MM/dd/yyyy h:mm");
Notice the uppercase/lowercase mM difference.
Also if you will always deal with the same datetime format string, you can make it easier by writing them as C# extension methods.
public static class DateTimeMyFormatExtensions
{
public static string ToMyFormatString(this DateTime dt)
{
return dt.ToString("MM/dd/yyyy");
}
}
public static class StringMyDateTimeFormatExtension
{
public static DateTime ParseMyFormatDateTime(this string s)
{
var culture = System.Globalization.CultureInfo.CurrentCulture;
return DateTime.ParseExact(s, "MM/dd/yyyy", culture);
}
}
EXAMPLE: Translating between DateTime/string
DateTime now = DateTime.Now;
string strNow = now.ToMyFormatString();
DateTime nowAgain = strNow.ParseMyFormatDateTime();
Note that there is NO way to store a custom DateTime format information to use as default as in .NET most string formatting depends on the currently set culture, i.e.
System.Globalization.CultureInfo.CurrentCulture.
The only easy way you can do is to roll a custom extension method.
Also, the other easy way would be to use a different "container" or "wrapper" class for your DateTime, i.e. some special class with explicit operator defined that automatically translates to and from DateTime/string. But that is dangerous territory.
Solution
DateTime.Now.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture)
I did like this
var datetoEnter= DateTime.ParseExact(createdDate, "dd/mm/yyyy", CultureInfo.InvariantCulture);
You can change the format too by doing this
string fecha = DateTime.Now.ToString(format:"dd-MM-yyyy");
// this change the "/" for the "-"
The following works for me.
string strToday = DateTime.Today.ToString("MM/dd/yyyy");

Display only date and no time in mvc [duplicate]

I have the following razor code that I want to have mm/dd/yyyy date format:
Audit Date: #Html.DisplayFor(Model => Model.AuditDate)
I have tried number of different approaches but none of that approaches works in my situation
my AuditDate is a DateTime? type
I have tried something like this and got this error:
#Html.DisplayFor(Model => Model.AuditDate.Value.ToShortDateString())
Additional information: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
Tried this:
#Html.DisplayFor(Model => Model.AuditDate.ToString("mm/dd/yyyy"))
No overload for method 'ToString' takes 1 arguments
If you use DisplayFor, then you have to either define the format via the DisplayFormat attribute or use a custom display template. (A full list of preset DisplayFormatString's can be found here.)
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime? AuditDate { get; set; }
Or create the view Views\Shared\DisplayTemplates\DateTime.cshtml:
#model DateTime?
#if (Model.HasValue)
{
#Model.Value.ToString("MM/dd/yyyy")
}
That will apply to all DateTimes, though, even ones where you're encoding the time as well. If you want it to apply only to date-only properties, then use Views\Shared\DisplayTemplates\Date.cshtml and the DataType attribute on your property:
[DataType(DataType.Date)]
public DateTime? AuditDate { get; set; }
The final option is to not use DisplayFor and instead render the property directly:
#if (Model.AuditDate.HasValue)
{
#Model.AuditDate.Value.ToString("MM/dd/yyyy")
}
I have been using this change in my code :
old code :
<td>
#Html.DisplayFor(modelItem => item.dataakt)
</td>
new :
<td>
#Convert.ToDateTime(item.dataakt).ToString("dd/MM/yyyy")
</td>
If you are simply outputting the value of that model property, you don't need the DisplayFor html helper, just call it directly with the proper string formatting.
Audit Date: #Model.AuditDate.Value.ToString("d")
Should output
Audit Date: 1/21/2015
Lastly, your audit date could be null, so you should do the conditional check before you attempt to format a nullable value.
#if (item.AuditDate!= null) { #Model.AuditDate.Value.ToString("d")}
Googling the error that you are getting provides this answer, which shows that the error is from using the word Model in your Html helpers. For instance, using #Html.DisplayFor(Model=>Model.someProperty). Change these to use something else other than Model, for instance: #Html.DisplayFor(x=>x.someProperty) or change the capital M to a lowercase m in these helpers.
You can use the [DisplayFormat] attribute on your view model as you want to apply this format for the whole project.
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public Nullable<System.DateTime> Date { get; set; }
#ChrisPratt's answer about the use of Display Template is wrong. The correct code to make it work is:
#model DateTime?
#if (Model.HasValue)
{
#Convert.ToDateTime(Model).ToString("MM/dd/yyyy")
}
That's because .ToString() for Nullable<DateTime> doesn't accept Format parameter.
For me it was enough to use
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime StartDate { set; get; }
I implemented the similar thing this way:
Use TextBoxFor to display date in required format and make the field readonly.
#Html.TextBoxFor(Model => Model.AuditDate, "{0:dd-MMM-yyyy}", new{#class="my-style", #readonly=true})
2. Give zero outline and zero border to TextBox in css.
.my-style {
outline: none;
border: none;
}
And......Its done :)
You could use Convert
<td>#Convert.ToString(string.Format("{0:dd/MM/yyyy}", o.frm_dt))</td>
In View Replace this:
#Html.DisplayFor(Model => Model.AuditDate.Value.ToShortDateString())
With:
#if(#Model.AuditDate.Value != null){#Model.AuditDate.Value.ToString("dd/MM/yyyy")}
else {#Html.DisplayFor(Model => Model.AuditDate)}
Explanation: If the AuditDate value is not null then it will format the date to dd/MM/yyyy, otherwise leave it as it is because it has no value.
After some digging and I ended up setting Thread's CurrentCulture value to have CultureInfo("en-US") in the controller’s action method:
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Here are some other options if you want have this setting on every view.
About CurrentCulture property value:
The CultureInfo object that is returned by this property, together
with its associated objects, determine the default format for dates,
times, numbers, currency values, the sorting order of text, casing
conventions, and string comparisons.
Source: MSDN CurrentCulture
Note: The previous CurrentCulture property setting is probably optional if the controller is already running with CultureInfo("en-US") or similar where the date format is "MM/dd/yyyy".
After setting the CurrentCulture property, add code block to convert the date to "M/d/yyyy" format in the view:
#{ //code block
var shortDateLocalFormat = "";
if (Model.AuditDate.HasValue) {
shortDateLocalFormat = ((DateTime)Model.AuditDate).ToString("M/d/yyyy");
//alternative way below
//shortDateLocalFormat = ((DateTime)Model.AuditDate).ToString("d");
}
}
#shortDateLocalFormat
Above the #shortDateLocalFormat variable is formatted with ToString("M/d/yyyy") works. If ToString("MM/dd/yyyy") is used, like I did first then you end up having leading zero issue. Also like recommended by Tommy ToString("d") works as well. Actually "d" stands for “Short date pattern” and can be used with different culture/language formats too.
I guess the code block from above can also be substituted with some cool helper method or similar.
For example
#helper DateFormatter(object date)
{
var shortDateLocalFormat = "";
if (date != null) {
shortDateLocalFormat = ((DateTime)date).ToString("M/d/yyyy");
}
#shortDateLocalFormat
}
can be used with this helper call
#DateFormatter(Model.AuditDate)
Update, I found out that there’s alternative way of doing the same thing when DateTime.ToString(String, IFormatProvider) method is used. When this method is used then there’s no need to use Thread’s CurrentCulture property. The CultureInfo("en-US") is passed as second argument --> IFormatProvider to DateTime.ToString(String, IFormatProvider) method.
Modified helper method:
#helper DateFormatter(object date)
{
var shortDateLocalFormat = "";
if (date != null) {
shortDateLocalFormat = ((DateTime)date).ToString("d", new System.Globalization.CultureInfo("en-US"));
}
#shortDateLocalFormat
}
.NET Fiddle
Maybe try simply
#(Model.AuditDate.HasValue ? Model.AuditDate.ToString("mm/dd/yyyy") : String.Empty)
also you can use many type of string format like
.ToString("dd MMM, yyyy")
.ToString("d") etc
This is the best way to get a simple date string :
#DateTime.Parse(Html.DisplayFor(Model => Model.AuditDate).ToString()).ToShortDateString()
Instead of
#Html.DisplayFor(Model => Model.AuditDate)
Use
#Model.AuditDate.ToString("MM/dd/yyyy")
This style renders the date as: 06/02/2022.
You can style your string accordingly to how you need it.
I had a similar issue on my controller and here is what worked for me:
model.DateSigned.HasValue ? model.DateSigned.Value.ToString("MM/dd/yyyy") : ""
"DateSigned" is the value from my model
The line reads, if the model value has a value then format the value, otherwise show nothing.
Hope that helps
You can use this instead of using #html.DisplayFor().
#Convert.ToString(string.Format("{0:dd/MM/yyyy}", Model.AuditDate))
You just need To set Data Annotation in your Model.
[DisplayFormat(ApplyFormatInEditMode = true,DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime AuditDate {get; set;}
On view(cshtml page)
#Html.DisplayFor(model => model.AuditDate)
Nothing else you need to do.
Hope its useful.
See this answer about the No overload for method 'ToString' takes 1 arguments error.
You cannot format a nullable DateTime - you have to use the DateTime.Value property.
#Model.AuditDate.HasValue ? Model.AuditDate.Value.ToString("mm/dd/yyyy") : string.Empty
Tip: It is always helpful to work this stuff out in a standard class with intellisense before putting it into a view. In this case, you would get a compile error which would be easy to spot in a class.

How to get TextBoxFor to round, based on Entity Property Annotations, using MVC3 ASP.NET 4.5 and EF6

I am using MVC3, ASP.NET 4.5, EF6, SQL Server 2008, C# , Razor.
I have created a POCO Entity class as the interface to my data using EF6.
I would like to have my decimal (20,4) properties round up after saving from a form. At present the first 4 decimals are taken irrespective of the 5th decimal ie no rounding
I get:
1.234567 -> 1.2345
I want:
1.234567 -> 1.2346
It would be ideal to specific this at the entity property level using annotations. I have played with DataFormatString which works well with "DisplayFor", but not for "TextBoxFor".
#Html.TextBoxFor(model => model.Decimal1, new { style = "width:110px" })
My Entity property code is:
[System.ComponentModel.DataAnnotations.DisplayFormat(DataFormatString = #"{0:G29}")]
[System.ComponentModel.DataAnnotations.RegularExpression(#"^[0-9]\d*(.\d+)?$", ErrorMessage = #"* Must be a number")]
[System.ComponentModel.DisplayName("Decimal1 Value")]
public virtual global::System.Nullable<decimal> Decimal1
{
get
{
return _Decimal1;
}
set
{
_Decimal1 = value;
}
}
How can I get #Html.TextBoxFor to pick up annotation rounding instructions for decimals like DisplayFor does?
Thank you in advance.
There are no way to use [DisplayFormat(DataFormatString = "{0:F4}")] attribute with The Fixed-Point ("F") Format Specifier that you need with TextBoxFor helper. But you can specify format using one of helper overloads like this:
#Html.TextBoxFor(model => model.Decimal1, "{0:F4}" , new { #style = "width:110px" })

Resources