ASP.NET MVC Date input format - asp.net-mvc

I have a textbox with date type:
#Html.TextBoxFor(m => m.DateOfBirth, new { #class = "form-control", type = "date" })
of the model's field DateOfBirth
[Required]
[DataType(DataType.Date)]
public DateTime DateOfBirth { get; set; } // Дата рождения
But date format is static mm/dd/yy which is wrong for Russian (dd/mm/yy). Of course I can set date format manually, but the system is multi-lingual and has English language as well as Russian, Kyrgyz, Uzbek (they all use European formats). When a user change a language
Thread.CurrentThread.CurrentCulture =CultureInfo.CreateSpecificCulture(lang);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
He supposed to see appropriate date format. But somewhy it doesn't happen :(
I have explored that the format depends on the language the browser uses. But chrome can't be displayed in Kyrgyz language...

You can accomplish what you want using the jquery.ui datepicker. By using it (or any other library that provides a similar functionality) you can easily maintain a consistent UX across multiple browsers, while with the standard HTML5 date inputs (<input type="date" />) you'll have browser-specific behaviour.
You can simply set the datepicker "regional" when loading your page. It seems that one of your goals is to be able to address multiple languages, I would recommend sticking with the "localization" idea rather than just setting the dateFormat attribute. If jquery ui does not provide a localization for the culture you are looking for, create one.
I've created a simple example where you can see the localization working in client-side. The idea would be very similar, but in your case it would be in the server-side: https://jsfiddle.net/ipvalverde/wxLxLe7p/9/
Regarding ASP.net MVC, I would suggest you to create a Razor View to setup all your datepicker elements on screen with your culture info. Something like this:
#{
_Layout = null;
}
var currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
string cultureCode = currentCulture.Name;
string datepickerLocalization = // Convert the thread culture name to datepicker culture name...
<script>
$(function () {
$.datepicker.setDefaults($.datepicker.regional["#datepickerLocalization"]);
})
</script>
Make sure you have loaded the javascripts with localization for the supported languages.
Let me know if this helps.

Related

Annotation Validation in Asp.net MVC just accept MM/dd/yyyy format

I have spent several hours reading a lot of articles, but I still cannot solve my issue.
I have a DateTime type property in my model:
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public System.DateTime StartTime { get; set; }
I have set the format to dd/MM/yyyy, so I expect a date like 14/12/2014 to be accepted. However, the validation always fails with the message: The field StartTime must be a date. I tried to input 12/14/2014 and it's ok.
Following several articles I have read, I tried to edit the format in razor code like:
#Html.TextBoxFor(model => model.StartTime, "{0:dd/MM/yyyy}")
And try using EditorFor like ataravati said in the below answer:
#Html.EditorFor(model => model.StartTime)
Or, change the culture in web.config to a culture in which day goes before month like GB:
<system.web>
<globalization uiCulture="en" culture="en-GB"/>
</system.web>
But, none of them work for me.
I tried using just a text input and input the date manually (not using any control like jqueryUI). However the validation still not accept my manually input if it's in dd/MM/yyyy format.
Could anyone show me the issue or show me the way to figure it out what the issue is?
UPDATE:
For someone who may have the same issue as me.
Following the post that Stephen mentions below, we have to create a 'date' validation to overwrite the default one of annotation validation. The custom validate we create will allow the format we want.
However, after that, the posted data to controller may not contain that data (in my case all datetime value is set to default datetime). The reason is the culture setting doesn't accept your format. We can change the culture setting in web.config but i don't think it's the best way because it can impact other value type (currency, number....) in your project. In my way, i create a custom ModelBinder for binding Datetime in the right format (an example here: http://www.codeproject.com/Articles/605595/ASP-NET-MVC-Custom-Model-Binder).
The above solution looks complicated. It shouldn't be so just for passing validation but up to now, i don't find anything better. Because of that, if someone have better solution that let annotation validation validates datetime value in format correctly, please share it.
The ApplyFormatInEditMode option only works when you use #Html.EditorFor, not #Html.TextBoxFor. Change your razor code to this:
#Html.EditorFor(model => model.StartTime)
Actually one thing that has been a life saver for me is as follows, and you don't need any data annotations (unless you want them etc):
#Html.TextBoxFor(m => m.StartDate, new { #Value = Model.StartDate.ToString("dd-MMM-yyyy") })
The above format can of course be changed to whatever.
Of course a popular thing to do is add say a datepicker too. I am using jQuery UI datepicker for ease of use:
#Html.TextBoxFor(model => model.StartDate, new { #Value = Model.StartDate.ToString("dd-MMM-yyyy"), #class = "form-control datepicker" })
My view model class example is shown below for completeness:
[DisplayName("Start Date")]
[Required(ErrorMessage = "An start date must be supplied")]
public DateTime StartDate { get; set; }
Hope it helps.

Time Format for DateTime field is not shown in the edit mode Asp Mvc

In my Model I have the following :
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:H:mm}")]
public DateTime _time { get; set; }
In my Edit View in the Textbox the value that is set is the full Date and time and when ever i try manually to edit the value through the browser the jQuery Validations Yields an error that the date format is not correct
while I'm adding ApplyFormatInEditMode=true why in the textbox I'm getting the Full Date the the formated one (only time) and why the jQuery validator throw error when the format is time only without date and how can I by pass it?
You should use Html.EditorFor and not Html.TextBoxFor if you want the custom format to be applied:
#Html.EditorFor(x => x._time)
Also by naming a property _time you are violating at least 2 C# naming conventions (property names start with an uppercase letter and not with an underscore).

Custom EditorTemplate not being used in MVC4 for DataType.Date

I'm upgrading an MVC3 application to MVC4 using the instructions from Microsoft. Everything went fairly smoothly - except a few of my date model properties are now rendering differently. For example, one of these properties is defined in the viewmodel like this:
[Required(ErrorMessage = "Required")]
[DataType(DataType.Date)]
[RegularExpression(#"([1-9]|0[1-9]|1[012])...",
ErrorMessage = "Format is mm/dd/yyyy")]
[FormatHint("mm/dd/yyyy")]
[InputSize("small")]
public string Date { get; set; }
Before upgrading to MVC4, this would be rendered via calling #Html.EditorFor(m => m.Date) which would use a custom EditorTemplate - the String.cshtml template (since it's a string!). I have some custom data annotations that formats the html so it utilizes a field layout, jQueryUI, and twitter Bootstrap on the client side. The validation is done via jquery validation unobtrusive. Anyhow, this is how it previously rendered:
Now that I'm using MVC4, the String.cshtml editor template is not being called for this property any longer. It renders like this (in Chrome using the HTML5 editor stuff, I assume):
The input element looks pretty much the same - all the jQuery validation bits are in there - the only difference seems to be the type attribute is now type="date", where before it was type="text".
I'd like to continue using the String.cshtml EditorTemplate for this datatype. I'm thinking there might be a data annotation that I can put on the ViewModel property to provide a TemplateHint for #Html.EditorFor(...). If not this, I'd like to know the custom EditorTemplate that I can write to hijack MVC4's formatting (I've already tried DateTime.cshtml - it's not being called either). If not either of those, then I'm open to suggestions on how to get my property rendering like it used to.
In MVC4, the used template is determinated from :
The UIHintAttribute if any
The DataTypeAttribute if any
The type of the property
In MVC3, the DataTypeAttribute was not used.
Your property has a
[DataType(DataType.Date)]
so the template Date.cshtml is used. If it does not exists, default rendering is executed.
You have two options to resolve your problem :
Add a UIHint("String") on your property, or
Rename your editor template from String.cshtml to Date.cshtml

How do I make Html.TextBoxFor DateTime accept user input of dd.MM.yy

I'm trying to make a page where the user can search for articles. There is an option to limit the search based on a FromDate and a ToDate. Both of these are DateTime.
The user is asked to enter the date on the form dd.MM.yyas this is normal in our country. I can see the date in the URL after submitting the form and it looks as I want it to. The problem however is that MVC3 assumes the format is MM.dd.yy. How can I change this?
Some code:
This is the Razor code I use
<div class="toDate" >
<label>til dato</label>
#Html.TextBoxFor(m => m.DateTo, new { placeholder = "dd.mm.yy" })
</div>
And in the model all I have is:
public DateTime DateTo { set; get; }
I have tried using EditorFor, but I lose my placeholder text.
In short: How do I make my MVC3 model accept a DateTime input from the user on the form dd.MM.yy
If my question isn't clear enough, let me know and I'll try to clarify.
EDIT:
It appears that I need some clarification, so I'll try to do that by making a scenario:
The user enters his search criteria. He sets a DateFrom and a DateTo in two text boxes.
The form is submitted and posted back to the server.
On the server the DateTime object is treated on the form MM.dd.yy. I wish for it to be interpreted as dd.MM.yy.
I hope that helps.
[DisplayFormat(DataFormatString = "{0:dd MM yy}")]
pubilc DateTime DateTo { get; set }
Try setting up a custom validation attribute where you validate the date format according to your liking.
Here's a nice tutorial for it: http://msdn.microsoft.com/en-us/gg618485 (It's not as difficulty as it might seem at first, and can be really helpful).
Alternatively just build a regex validation attribute with something like:
RegularExpression(#"[0-3][0-9]\.[0-1][0-9].[0-9][0-9]")]
Above regex isn't perfect, but serves as an example.
Edit: If 3nigma's solution works for you that is obviously highly preferable to mine. :)

Culture issues in ASP.NET MVC 3

I want to display multiple languages and UI cultures on my website. I have enabled the IIS 7 flag which picks up culture from the browser automatically as so:
<globalization
enableClientBasedCulture="true"
culture="en-GB"
uiCulture="auto:en"/>
This works perfectly in that the correct Resources files are loaded, and the correct culture is displayed (0.00 for GB; 0,00 for DE).
However this has had an unexpected problem of interferring with my external services, for example here is the code for interfacing with PayPal.
var paymentDetails = new PaymentDetailsType
{
ItemTotal = new BasicAmountType
{
currencyID = currencyCode,
Value = basket.SubTotal.ToString("0.00")
},
...
}
This code basically creates a string formatted like so '50.25', however as PayPal always requires a dot decimal point, when a culture is selected that has a comma as a decimal point (for example DE - German) the ToString("0.00") generates '50,25' and so my code fails.
What would be the best method to correct this? I still want the culture set to the user's culture, however I want to set certain parts of my code to use my own culture.
I know I can feed in a specific culture to the ToString() method, but this seems very hackish. Any more professional clean approaches?
Have a look at the InvariantCulture.
Value = basket.SubTotal.ToString("0.00", CultureInfo.InvariantCulture)
Here's a link to the overload of ToString() that takes a second System.IFormatProvider parameter:
http://msdn.microsoft.com/en-us/library/d8ztz0sa.aspx

Resources