locked
How to set current DateTime.Today as default field value in edit/insert mode RRS feed

  • Question

  • User-586832860 posted

    Hello guys,

    I am trying to set one of fields (LastModifiedOn) in edit mode to the current DateTime.Today (read only) value when user click on Edit link in the list of entities (datagrid). Before I do that, the list (datagrid) should display value from datasource i.e. whatever was persisted at the time of last modification.

    If I do in partial class something like this:

                           if (DateTime.Parse(LastModifiedOn) != DateTime.Now.Date)

                          {

                             _LastModifiedOn = DateTime.Now.Date;

                          }


    it sets in edit template value as .Today but also all values (for each row) in grid as DateTime.Today, so I cannot see in grid previous value.
    Is it possible to change database value to DateTime.Today value during databinding when I go to edit mode and how to do it?

    Monday, June 29, 2009 11:22 AM

Answers

  • User-586832860 posted

    OK that might be solution, but what about other audit properties, for examle "ModifiedBy"?

    I've found workable solution combininig two articles:
    http://weblogs.asp.net/craigshoemaker/archive/2008/05/08/passing-arguments-to-a-dynamic-data-field-template-from-a-uihint-attribute.aspx?CommentPosted=true#commentmessage
    and
    http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/Q_23874343.html

    Code follows:
    [MetadataType(typeof(Intervew_Metadata))]
    public partial class Interview{}

    public class Intervew_Metadata
    {
        [UIHint("DateTimeAutoFill")]
        public object CreatedOn;

        [UIHint("DateTimeAutoFill",null,"Overwrite","true")]
        public object ModifiedOn;
    }

    <%@ Control Language="C#" CodeFile="DateTimeAutoFill_Edit.ascx.cs" Inherits="DateTime_EditField" >
    <%@ Register Assembly="Infragistics35.WebUI.WebDateChooser.v8.1, Version=8.1.20081.1000, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb"
        Namespace="Infragistics.WebUI.WebSchedule" TagPrefix="igsch" >

    <igsch:WebDateChooser value="<%# FieldValueEditString %>" id="WebDateChooser1" runat="server">
    </igsch:WebDateChooser> 

    <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator1" controltovalidate="WebDateChooser1" display="Dynamic" enabled="false"></asp:RequiredFieldValidator>
       
    <asp:DynamicValidator runat="server" id="DynamicValidator1" controltovalidate="WebDateChooser1" display="Dynamic"></asp:DynamicValidator>

    using System.ComponentModel.DataAnnotations;

    ...

    protected override void OnPreRender(EventArgs e)
    {
    UIHintAttribute hint = null;
    bool overwrite = false;

    hint = (UIHintAttribute)this.Column.Attributes[typeof(UIHintAttribute)];

    if (hint != null)
    {
    if (hint.ControlParameters.Count > 0)
    {
    if (hint.ControlParameters["Overwrite"] != null)
    {
    overwrite = Convert.ToBoolean(hint.ControlParameters["Overwrite"]);
    }
    }
    }

    if (overwrite)
    {
    this.WebDateChooser1.Value = DateTime.Now.ToString();
    }
    else
    {
    if (string.IsNullOrEmpty(this.WebDateChooser1.Value.ToString()))
    {
    this.WebDateChooser1.Value = DateTime.Now.ToString();
    }
    }

    base.OnPreRender(e);

    }
    and
    partial void OnContextCreated()
            {
                this.SavingChanges += new
                    System.EventHandler(OnSavingChanges);
            }

            /// <summary>
            /// Updates modified by and date fields for updates
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void OnSavingChanges(object sender, System.EventArgs e)
            {
                var stateManager = ((TransitScheduleEntities)sender).ObjectStateManager;
                var changedEntities = stateManager.GetObjectStateEntries(EntityState.Modified);

                foreach (ObjectStateEntry stateEntryEntity in changedEntities)
                {
                    int modBy = stateEntryEntity.CurrentValues.GetOrdinal("ModifiedBy");
                    int modDate = stateEntryEntity.CurrentValues.GetOrdinal("DateModified");
                    if (modBy > 0)
                    {
                        stateEntryEntity.CurrentValues.SetValue(modBy, HttpContext.Current.User.Identity.Name);
                    }
                    if (modDate > 0)
                    {
                        stateEntryEntity.CurrentValues.SetValue(modDate, DateTime.Now);
                    }
                }
            }
    This fits my needs. What do you think, is there better approach?
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 30, 2009 1:41 PM

All replies

  • User1965317228 posted

    You can create a new FieldTemplate for display this info, and in the method ExtractValue, you set the current DateTime

            protected override void ExtractValues(IOrderedDictionary dictionary)
            {
                dictionary[Column.Name] = DateTime.Today;
            }


     and if you wnat display DateTime.Today also in visualization, you can set this value in the label the you have in the FieldTemplate.

    For use this FieldTemplate, you must use a UHint attribute.

    Monday, June 29, 2009 12:09 PM
  • User-586832860 posted

     After template is created and UIHint used, control displays correct current DateTime.Today value but it doesn't save it to database. It persists the old value.

    Monday, June 29, 2009 6:53 PM
  • User896152122 posted

    I know DynamicData is a nice hammer, but what's wrong with using a Default Value of GetDate() in SQL Server on the LastModified column?

    If you're using EF1 you'll also have to add StoreGeneratedValue="Computed" to the Entity column or it will expect your code to provide a value for the field.

    Dave

    Tuesday, June 30, 2009 3:25 AM
  • User-330204900 posted

     The easyest way to do this is to add some saving logic to the context see:

    L2S: see my Automatic Column Update

    EF: How to: Execute Business Logic When Saving Changes (Entity Framework)<!---->

    Tuesday, June 30, 2009 3:38 AM
  • User-1005219520 posted

    As "how do I set default values" - this is a good question/approach. But specifically setting update time - it's very problematic. Update time should be set by the server with a trigger.

    Tuesday, June 30, 2009 12:45 PM
  • User-586832860 posted

    L2S might work well but  How to: Execute Business Logic When Saving Changes (Entity Framework) is related to validation and you can just throw exception but not set the value.

    Tuesday, June 30, 2009 1:32 PM
  • User-586832860 posted

    OK that might be solution, but what about other audit properties, for examle "ModifiedBy"?

    I've found workable solution combininig two articles:
    http://weblogs.asp.net/craigshoemaker/archive/2008/05/08/passing-arguments-to-a-dynamic-data-field-template-from-a-uihint-attribute.aspx?CommentPosted=true#commentmessage
    and
    http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/Q_23874343.html

    Code follows:
    [MetadataType(typeof(Intervew_Metadata))]
    public partial class Interview{}

    public class Intervew_Metadata
    {
        [UIHint("DateTimeAutoFill")]
        public object CreatedOn;

        [UIHint("DateTimeAutoFill",null,"Overwrite","true")]
        public object ModifiedOn;
    }

    <%@ Control Language="C#" CodeFile="DateTimeAutoFill_Edit.ascx.cs" Inherits="DateTime_EditField" >
    <%@ Register Assembly="Infragistics35.WebUI.WebDateChooser.v8.1, Version=8.1.20081.1000, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb"
        Namespace="Infragistics.WebUI.WebSchedule" TagPrefix="igsch" >

    <igsch:WebDateChooser value="<%# FieldValueEditString %>" id="WebDateChooser1" runat="server">
    </igsch:WebDateChooser> 

    <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator1" controltovalidate="WebDateChooser1" display="Dynamic" enabled="false"></asp:RequiredFieldValidator>
       
    <asp:DynamicValidator runat="server" id="DynamicValidator1" controltovalidate="WebDateChooser1" display="Dynamic"></asp:DynamicValidator>

    using System.ComponentModel.DataAnnotations;

    ...

    protected override void OnPreRender(EventArgs e)
    {
    UIHintAttribute hint = null;
    bool overwrite = false;

    hint = (UIHintAttribute)this.Column.Attributes[typeof(UIHintAttribute)];

    if (hint != null)
    {
    if (hint.ControlParameters.Count > 0)
    {
    if (hint.ControlParameters["Overwrite"] != null)
    {
    overwrite = Convert.ToBoolean(hint.ControlParameters["Overwrite"]);
    }
    }
    }

    if (overwrite)
    {
    this.WebDateChooser1.Value = DateTime.Now.ToString();
    }
    else
    {
    if (string.IsNullOrEmpty(this.WebDateChooser1.Value.ToString()))
    {
    this.WebDateChooser1.Value = DateTime.Now.ToString();
    }
    }

    base.OnPreRender(e);

    }
    and
    partial void OnContextCreated()
            {
                this.SavingChanges += new
                    System.EventHandler(OnSavingChanges);
            }

            /// <summary>
            /// Updates modified by and date fields for updates
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void OnSavingChanges(object sender, System.EventArgs e)
            {
                var stateManager = ((TransitScheduleEntities)sender).ObjectStateManager;
                var changedEntities = stateManager.GetObjectStateEntries(EntityState.Modified);

                foreach (ObjectStateEntry stateEntryEntity in changedEntities)
                {
                    int modBy = stateEntryEntity.CurrentValues.GetOrdinal("ModifiedBy");
                    int modDate = stateEntryEntity.CurrentValues.GetOrdinal("DateModified");
                    if (modBy > 0)
                    {
                        stateEntryEntity.CurrentValues.SetValue(modBy, HttpContext.Current.User.Identity.Name);
                    }
                    if (modDate > 0)
                    {
                        stateEntryEntity.CurrentValues.SetValue(modDate, DateTime.Now);
                    }
                }
            }
    This fits my needs. What do you think, is there better approach?
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 30, 2009 1:41 PM
  • User-586832860 posted

    How/Where  would you do that (StoreGeneratedValue="Computed")? I don't see any place where I can set it in designer.

    Tuesday, June 30, 2009 1:50 PM
  • User-1005219520 posted

    You need to create and insert/update trigger on SQL Server.

    Tuesday, June 30, 2009 2:22 PM
  • User-1005219520 posted

    >>OK that might be solution, but what about other audit properties, for examle "ModifiedBy"? Right - that's why I said this is a good question/approach (for other props - but not modified time). For modified user - the SavingChanges approach works well.

    Tuesday, June 30, 2009 2:25 PM
  • User-586832860 posted

    See, that is completely opposite to the basic concept of EntityFramework as you can read:

    "the Entity Framework supports code that is independent of any particular data storage engine or relational schema"

    on http://msdn.microsoft.com/en-us/library/bb386876.aspx.

    I hope this promise will not be broken.

    Besides, I was wondering, who has marked this topic as resolved?


    Tuesday, July 14, 2009 1:21 AM