In my ASP.NET MVC 5 dwith EF 6 project, I have a database where datetime format is stored as string like "dd-MM-yyyy". User can change this format any time. User will use the given format in the date fields in the view. But when they will post that. Automatically it will bind as a DateTime for that property. I am statically handling it by the following code
[DataType(DataType.Time), DisplayFormat(DataFormatString = "{HH:mm}", ApplyFormatInEditMode = true)]
public DateTime? EndingTime { get; set; }
public string EndingTimeValue
{
get
{
return EndingTime.HasValue ? EndingTime.Value.ToString("HH:mm") : string.Empty;
}
set
{
EndingTime = DateTime.Parse(value);
}
}
but I know it's not a best way to do that. There may need a model binder or filter or any kind of custom attribute. I will be greatly helped if you give me a efficient solution with sample code. Thanks in advance.
NB: I am using razor view engine. and my solution consists of 7 projects. So there is no chance of using Session in model. Again I have a base repository class for using entity framework.
People usually store the datetime in the database as a datetime.
Then wherever you do a translation from datetime to string that datetime can be displayed in a format that depends on the culture of the viewer.
By doing this you can quickly make a page with datetime formats that will format the datetimes nicely wherever you are.
change the culture you pass to the toString and the format changes.
please see this MSDN page for more info about it.
edit: (see comments below)
anywhere on server:
string WhatYouWant = yourTime.ToCustomFormat()
and create an extension method for the datetime that gets the format out of the database and returns a string in the correct format.
public static class MyExtensions
{
public static string ToCustomFormat(this DateTime yourTime)
{
// Get the following var out of the database
String format = "MM/dd/yyyy hh:mm:sszzz";
// Converts the local DateTime to a string
// using the custom format string and display.
String result = yourTime.ToString(format);
return result;
}
}
This will allow you to call it anywhere anytime on your server. You can't access the method client side in javascript. I hope this helps.
(To be honest I'm a new developer too and still have a lot to learn ^^)
I have tried many options regarding this problem. Now what I am doing is created an action filter to catch all the DateTime and nullable DateTime Fields. Here I am providing the binder.
public class DateTimeBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
DateTime date;
var displayFormat = SmartSession.DateTimeFormat;
if (DateTime.TryParseExact(value.AttemptedValue, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
{
return date;
}
else
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName,"Invalid Format");
}
return base.BindModel(controllerContext, bindingContext);
}
}
in views the code I am formatting the date using same date format.
Related
I'm working on Angular (front-end) with C# (back-end) project going, and I'm going to use the input time <input type="time">
So, is the value a string, or should I save it as DateTime and get the time part only?
How should the property be on the backend and database?
public DateTime? Property { get; set; }
Or
public string Property { get; set; }
Save to Database in DateTime, do all business logic in DateTime, but when you want to display to view, it is smooth to convert to string. Bellow is a sample code that i use to help with this.
public string DateTimeToString(DateTime dateTime)
{
var stringDate = dateTime.ToString("dddd, dd/MM/yyyy HH:mm");
return stringDate;
}
You can format it however you wish, this will help to keep your DateTime on tables to look uniform, and removes the need to always convert to string at the presentation layer.
I have a list of objects in my collection and need to format the date on an object date property (NoteDate) to show dates in the format like "dd'/'MM'/'yyyy HH:mm:ss" whereas in database the format of the date is like '2015-02-19 00:00:00.000'. Below is my object
public class Note
{
public int Id { get; set; }
public string NoteText { get; set; }
public DateTime? NoteDate { get; set; }
}
and I populate the collection as below
var notesList= _uow.Find<Note>(n => n.FK == leadId).ToList();
how can we write the query to get the desired date format?
thanks
You are, properly, storing the date in a DateTime? object. DateTime is simply a storage mechanism.
What you are really interested in is how to display the DateTime in some UI.
So here's the steps your Date/Time is going to take:
Get returned as query content from the database
Get stored in the DateTime property
Be shown to the user
To format a value from a DateTime object there are several options - check out the methods on the DateTime class.
Your dates will be represented as a DateTime instance .. how .NET decides to represent dates.
When you're displaying them to your user/using them for display somewhere, you can simply format them at that point. For example:
var notesList = _uow.Find<Note>(n => n.FK == leadId).ToList();
var thirdNoteDateString = notesList[2].NoteDate.ToString("dd MM yyyy");
Or, perhaps in a Razor view (if this was an MVC application):
#foreach (var n in Model.Notes) {
<p>#n.NoteDate.ToString("dd MM yyyy")</p>
}
Hopefully that shows the difference. How the date is presented is up to you when you decide to present it.
you should not modify the content of your buisness object just for a Show purpose,
You should use a converter or a StringFormat like :
<TextBlock Text="{Binding Date, StringFormat={}{0:MM/dd/yyyy}}" />
see this question for more info
I am still getting my hands around MVC.
I have seen several similar questions, some custom code and various methods but I have not found something that works for me.
I have a search model that fills an HTML table with results inside of a partial view. I have this in my search results model:
public DateTime? BeginDateTime { get; set; }
Which is set to DateTime.Now in the controller. The user can specify that date and time to run a task with the search results' data on the model's POST call.
What I would like to do is validate that the date/time the user defined is at least 1 minute in the future. If this can be done as a client-side validation it will be better, but I am open to options as long as it works.
View:
Begin update: #Html.TextBoxFor(o => o.BeginDateTime, new { id="txtBegin" })
Thanks.
Create a new Attribute:
public class FutureDateAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return value != null && (DateTime)value > DateTime.Now;
}
}
Now in your model set this attribute:
[FutureDate(ErrorMessage="Date should be in the future.")]
public DateTime Deadline { get; set; }
This is another good way to check that the date selected is from the future.
public class FutureDate : ValidationAttribute
{
public override bool IsValid(object value)
{
DateTime dateTime;
var isValid = DateTime.TryParseExact(
//Getting the value from the user.
Convert.ToString(value),
//We want the user to enter date in this format.
"d mmm yyyy",
//It checks if the culture is us-en
CultureInfo.CurrentCulture,
//Mosh has no idea what this does.
DateTimeStyles.None,
//Output parameter.
out dateTime);
return (isValid && dateTime > DateTime.Now);
}
}
I have this code:
#Html.TextBoxFor(m => Model.MyDateTime)
MyDateTime - is DateTime object.
It shows correct date and time inside textbox: 09/10/2010 05:19:56 PM
But when I try to click submit button it shows that it is incorrect value. I use jquery.validate.unobtrusive.js file for validation.
The gist of the solution I pointed to in my comment is that you can use a specialized model for the view which contains a string representation instead of the DateTime type, which allows you to easily validate the value with RegularExpressionAttribute. When you receive this model on the server (as posted from the client), simply convert it to a corresponding database model.
public class ViewModel
{
[Required]
[RegularExpression("\d{2}-\d{2}-\d{4}\s\d{2}:\d{2}:\d{2}")]
public string MyDateTime { get; set; }
public Model ToPoco()
{
return new Model {
MyDateTime = DateTime.Parse(this.MyDateTime, "MM-dd-yyyy H:mm:ss")
};
}
}
public class Model
{
DateTime MyDateTime { get; set; }
}
data annotation will work for you!
You could use dataannotaion for validate yor model field properly. Using such annatation you could manualy prvide format of date in your annotation passing string pattern to it. And in that case it will perefectly working with default mvc validation.
I'm passing a date to my server in Invariant Culture, the following format
'mm/dd/yy'
The parameter binding in MVC fails to parse this date and returns null for the parameter. This is persumably because IIS is running on a machine using English culture ('dd/mm/yy' works just fine).
I want to override the parsing of all date on my server to use Invariant Culture like so...
Convert.ChangeType('12/31/11', typeof(DateTime), CultureInfo.InvariantCulture);
even when the date is part of another object...
public class MyObj
{
public DateTime Date { get; set; }
}
My controller method is something like this....
public ActionResult DoSomethingImportant(MyObj obj)
{
// use the really important date here
DoSomethingWithTheDate(obj.Date);
}
The date is being sent as Json data like so....
myobj.Date = '12/31/11'
I've tried adding an implementation of IModelBinder to the binderDictionary in the global.asax
binderDictionary.Add(typeof(DateTime), new DateTimeModelBinder());
That doesn't work, and neither does
ModelBinders.Binders.Add(typeof(DateTime), new DataTimeModelBinder());
This seems like some ppl would want to do all the time. I can't see why you would parse dates etc. in the current culture on the server. A client would have to find out the culture of the server just to format dates the server will be able to parse.....
Any help appreciated!
I've solved the problem here, what I had missed was that in the object, the datetime was nullable
public class MyObj
{
public DateTime? Date { get; set; }
}
Hence my binder wasn't being picked up.
If anyone is interested, this is what I did....
In the global.asax added the following
binderDictionary.add(typeof(DateTime?), new InvariantBinder<DateTime>());
Created an invariant binder like so
public class InvariantBinder<T> : IModelBinder
{
public object BindModel(ControllerContext context, ModelBindingContext binding)
{
string name = binding.ModelName;
IDictionary<string, ValueProviderResult> values = binding.ValueProvider;
if (!values.ContainsKey(name) || string.IsNullOrEmpty(values[names].AttemptedValue)
return null;
return (T)Convert.ChangeType(values[name].AttemptedValue, typeof(T), CultureInfo.Invariant);
}
}
Hope this comes in handy for someone else.....
Is your problem that your custom model binder is unable to parse some of the input dates or that your custom model binder never gets called? If it's the former then trying to use the culture of the user's browser might help.
public class UserCultureDateTimeModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object value = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (value == null)
return null;
// Request.UserLanguages could have multiple values or even no value.
string culture = controllerContext.HttpContext.Request.UserLanguages.FirstOrDefault();
return Convert.ChangeType(value, typeof(DateTime), CultureInfo.GetCultureInfo(culture));
}
}
...
ModelBinders.Binders.Add(typeof(DateTime?), new UserCultureDateTimeModelBinder());
Is it possible to pass the date to the server in ISO 8601 format? I think the server would parse that correctly regardless of its own regional settings.