Setting the default value for the DateTime property to DateTime.Now inside the System.ComponentModel Default Attrbute value

Does anyone know how I can specify the default value for the DateTime property using the System.ComponentModel DefaultValue attribute?

For example, I try this:

[DefaultValue(typeof(DateTime),DateTime.Now.ToString("yyyy-MM-dd"))] public DateTime DateCreated { get; set; } 

And he expects value to be a constant expression.

This is in the context of using ASP.NET dynamic data. I do not want to align the DateCreated column, but just supply DateTime.Now if it is not. I use Entity Framework as a data layer

Greetings

Andrew

+84
c # entity-framework dynamic-data
Mar 27 '09 at 18:49
source share
16 answers

You cannot do this with an attribute because it is just meta-information generated at compile time. Just add code to the constructor to initialize the date, if necessary, create a trigger and process the missing values ​​in the database, or embed getter so that it returns DateTime.Now if the support field is not initialized.

 public DateTime DateCreated { get { return this.dateCreated.HasValue ? this.dateCreated.Value : DateTime.Now; } set { this.dateCreated = value; } } private DateTime? dateCreated = null; 
+89
Mar 27 '09 at 18:51
source share

Add a DateTime Property Below

 [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
+26
May 19 '17 at 12:39
source share

There is no reason why I can think of it as impossible to do through an attribute. Perhaps this is due to the backlog of Microsoft. Who knows.

The best solution I found is to use the defaultValueSql parameter in the first code migration.

 CreateTable( "dbo.SomeTable", c => new { TheDateField = c.DateTime(defaultValueSql: "GETDATE()") }); 

I don’t like the frequent reference solution for setting it in the constructor of the entity class, because if anything other than the Entity Framework inserts a record into this table, the date field will not get the default value. And the idea of ​​using a trigger to handle this case just seems wrong to me.

+20
Apr 16 '15 at 16:18
source share

It is possible and quite simple:

for DateTime.MinValue

 [System.ComponentModel.DefaultValue(typeof(DateTime), "")] 

for any other value, specify the string that represents the desired DateTime value as the last argument to DefaultValueAttribute .

This value must be a constant expression and is required to create an object ( DateTime ) using TypeConverter .

+11
Feb 15 '12 at 10:41
source share

A simple solution if you are using the Entity Framework is to add a partical class and define a constructor for the object, since the environment does not define it. For example, if you had an object named Example, you would put the following code in a separate file.

 namespace EntityExample { public partial class Example : EntityObject { public Example() { // Initialize certain default values here. this._DateCreated = DateTime.Now; } } } 
+6
Nov 18 '10 at 17:39
source share

I think the easiest solution is to install

 Created DATETIME2 NOT NULL DEFAULT GETDATE() 

in the column declaration, and in VS2010, the EntityModel designer sets the corresponding column property StoreGeneratedPattern = Computed .

+5
Apr 17 '12 at 7:32
source share

Just think about setting its value in the constructor of the entity class

 public class Foo { public DateTime DateCreated { get; set; } public Foo() { DateCreated = DateTime.Now; } } 
+4
Apr 23 '13 at 21:39 on
source share

I need a UTC timestamp as the default and a modified Daniel solution like this:

  [Column(TypeName = "datetime2")] [XmlAttribute] [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")] [Display(Name = "Date Modified")] [DateRange(Min = "1900-01-01", Max = "2999-12-31")] public DateTime DateModified { get { return dateModified; } set { dateModified = value; } } private DateTime dateModified = DateTime.Now.ToUniversalTime(); 

In the DateRangeAttribute tutorial, see this terrible blog post

+3
May 25 '11 at 1:38
source share

Creating a new attribute class is a good suggestion. In my case, I wanted to specify "default (DateTime)" or "DateTime.MinValue" so that the Newtonsoft.Json serializer would ignore DateTime members without real values.

 [JsonProperty( DefaultValueHandling = DefaultValueHandling.Ignore )] [DefaultDateTime] public DateTime EndTime; public class DefaultDateTimeAttribute : DefaultValueAttribute { public DefaultDateTimeAttribute() : base( default( DateTime ) ) { } public DefaultDateTimeAttribute( string dateTime ) : base( DateTime.Parse( dateTime ) ) { } } 

Without the DefaultValue attribute, the JSON serializer outputs "1/1/0001 12:00:00 AM" even if the DefaultValueHandling.Ignore parameter is set.

+3
Jun 03 2018-11-11T00:
source share

There is a way. Add these classes:

DefaultDateTimeValueAttribute.cs

 using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using Custom.Extensions; namespace Custom.DefaultValueAttributes { /// <summary> /// This class DefaultValue attribute allows the programmer to use DateTime.Now as a default value for a property. /// Inspired from https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19. /// </summary> [AttributeUsage(AttributeTargets.Property)] public sealed class DefaultDateTimeValueAttribute : DefaultValueAttribute { public string DefaultValue { get; set; } private object _value; public override object Value { get { if (_value == null) return _value = GetDefaultValue(); return _value; } } /// <summary> /// Initialized a new instance of this class using the desired DateTime value. A string is expected, because the value must be generated at runtime. /// Example of value to pass: Now. This will return the current date and time as a default value. /// Programmer tip: Even if the parameter is passed to the base class, it is not used at all. The property Value is overridden. /// </summary> /// <param name="defaultValue">Default value to render from an instance of <see cref="DateTime"/></param> public DefaultDateTimeValueAttribute(string defaultValue) : base(defaultValue) { DefaultValue = defaultValue; } public static DateTime GetDefaultValue(Type objectType, string propertyName) { var property = objectType.GetProperty(propertyName); var attribute = property.GetCustomAttributes(typeof(DefaultDateTimeValueAttribute), false) ?.Cast<DefaultDateTimeValueAttribute>() ?.FirstOrDefault(); return attribute.GetDefaultValue(); } private DateTime GetDefaultValue() { // Resolve a named property of DateTime, like "Now" if (this.IsProperty) { return GetPropertyValue(); } // Resolve a named extension method of DateTime, like "LastOfMonth" if (this.IsExtensionMethod) { return GetExtensionMethodValue(); } // Parse a relative date if (this.IsRelativeValue) { return GetRelativeValue(); } // Parse an absolute date return GetAbsoluteValue(); } private bool IsProperty => typeof(DateTime).GetProperties() .Select(p => p.Name).Contains(this.DefaultValue); private bool IsExtensionMethod => typeof(DefaultDateTimeValueAttribute).Assembly .GetType(typeof(DefaultDateTimeExtensions).FullName) .GetMethods() .Where(m => m.IsDefined(typeof(ExtensionAttribute), false)) .Select(p => p.Name).Contains(this.DefaultValue); private bool IsRelativeValue => this.DefaultValue.Contains(":"); private DateTime GetPropertyValue() { var instance = Activator.CreateInstance<DateTime>(); var value = (DateTime)instance.GetType() .GetProperty(this.DefaultValue) .GetValue(instance); return value; } private DateTime GetExtensionMethodValue() { var instance = Activator.CreateInstance<DateTime>(); var value = (DateTime)typeof(DefaultDateTimeValueAttribute).Assembly .GetType(typeof(DefaultDateTimeExtensions).FullName) .GetMethod(this.DefaultValue) .Invoke(instance, new object[] { DateTime.Now }); return value; } private DateTime GetRelativeValue() { TimeSpan timeSpan; if (!TimeSpan.TryParse(this.DefaultValue, out timeSpan)) { return default(DateTime); } return DateTime.Now.Add(timeSpan); } private DateTime GetAbsoluteValue() { DateTime value; if (!DateTime.TryParse(this.DefaultValue, out value)) { return default(DateTime); } return value; } } } 

DefaultDateTimeExtensions.cs

 using System; namespace Custom.Extensions { /// <summary> /// Inspired from https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19. See usage for more information. /// </summary> public static class DefaultDateTimeExtensions { public static DateTime FirstOfYear(this DateTime dateTime) => new DateTime(dateTime.Year, 1, 1, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); public static DateTime LastOfYear(this DateTime dateTime) => new DateTime(dateTime.Year, 12, 31, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); public static DateTime FirstOfMonth(this DateTime dateTime) => new DateTime(dateTime.Year, dateTime.Month, 1, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); public static DateTime LastOfMonth(this DateTime dateTime) => new DateTime(dateTime.Year, dateTime.Month, DateTime.DaysInMonth(dateTime.Year, dateTime.Month), dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); } } 

And use DefaultDateTimeValue as an attribute of your properties. The value for entering your validation attribute is things like "Now" that will be displayed at runtime from an DateTime instance created with Activator. The source code is inspired by this thread: https://code.msdn.microsoft.com/A-flexible-Default-Value-11c2db19 . I modified it so that my class inherits from DefaultValueAttribute instead of ValidationAttribute.

+1
Jan 17 '17 at 18:37
source share

How you deal with this at the moment depends on which model you use Linq for SQL or EntityFramework?

In L2S you can add

 public partial class NWDataContext { partial void InsertCategory(Category instance) { if(Instance.Date == null) Instance.Data = DateTime.Now; ExecuteDynamicInsert(instance); } } 

EF is a bit more complicated, see http://msdn.microsoft.com/en-us/library/cc716714.aspx for more information on EF logic logic.

0
Mar 27 '09 at 23:02
source share
 public DateTime DateCreated { get { return (this.dateCreated == default(DateTime)) ? this.dateCreated = DateTime.Now : this.dateCreated; } set { this.dateCreated = value; } } private DateTime dateCreated = default(DateTime); 
0
Jul 07 '10 at 17:00
source share

I know this post is a little old, but there is a suggestion that might help someone.

I used Enum to determine what needs to be set in the attribute constructor.

Property Declaration:

 [DbProperty(initialValue: EInitialValue.DateTime_Now)] public DateTime CreationDate { get; set; } 

Property constructor:

 Public Class DbProperty Inherits System.Attribute Public Property InitialValue As Object Public Sub New(ByVal initialValue As EInitialValue) Select Case initialValue Case EInitialValue.DateTime_Now Me.InitialValue = System.DateTime.Now Case EInitialValue.DateTime_Min Me.InitialValue = System.DateTime.MinValue Case EInitialValue.DateTime_Max Me.InitialValue = System.DateTime.MaxValue End Select End Sub End Class 

Listing:

 Public Enum EInitialValue DateTime_Now DateTime_Min DateTime_Max End Enum 
0
Mar 11 '15 at 18:14
source share

I think you can do this using StoreGeneratedPattern = Identity (set in the model constructor properties window).

I would not have guessed that this would be how to do it, but, trying to figure it out, I noticed that some of my date columns no longer correspond to CURRENT_TIMESTAMP() , and some do not. Checking the model, I see that the only difference between the two columns besides the name is that the default value StoreGeneratedPattern set to Identity .

I would not expect this to be so, but reading the description, it makes sense:

Determines whether the corresponding column in the database is automatically generated during insert and update operations.

Also, while this makes the database column the default “now”, I think it does not actually set the DateTime.Now property to POCO. This was not a problem for me, because I have a customized .tt file that already automatically sets all my date columns to DateTime.Now (it’s actually easy to change the .tt file yourself, especially if you have ReSharper and get the syntax highlighting plugin (newer versions of VS may already syntactically highlight .tt files, not sure.))

The problem is for me: how do I get the default database column so that existing queries that omitted this column still work? And the above setup worked for this.

I have not tested it yet, but it is also possible that setting this will interfere with setting your own explicit value. (I just came across this, primarily because EF6 Database First wrote this model for me.)

0
Apr 17 '17 at 1:36 on
source share

Just found that this is looking for something else, but in the new C # version you can use an even shorter version for this:

 public DateTime DateCreated { get; set; } = DateTime.Now; 
0
Nov 28 '17 at 9:39 on
source share

I also wanted this and came up with this solution (I use only part of the date - the default time does not make sense like the default for PropertyGrid):

 public class DefaultDateAttribute : DefaultValueAttribute { public DefaultDateAttribute(short yearoffset) : base(DateTime.Now.AddYears(yearoffset).Date) { } } 

This simply creates a new attribute that you can add to the DateTime property. For example. if the default is DateTime.Now.Date:

 [DefaultDate(0)] 
-four
Aug 27 '10 at 9:47
source share



All Articles