none
setting default values RRS feed

  • Question

  • hello
    i try to setup default value by using an IValidatableObject. Please see the default #region.
    The code for the scalar types runs ok, but not for the ThirdParty* (a little more far in the post the definition of the class): 
     
    if ( ThirdPartyCharged == null ) ThirdPartyCharged = ThirdParty;

    But from outside the  gDocument class the following code runs well:
     
    gDocument gDoc = new gDocument();
    gDoc.ThirdParty = efgdr.GetThirdPartyById("xyz");
    gDoc.ThirdPartyCharged = gDoc.ThirdParty;
    
    ---------- ----------
    The 'bad' code :
     
    public class gDocument : IValidatableObject {
      protected List<gLine> _lines;
      public gDocument () {
       _lines = new List<gLine>();
      }
    
      #region Properties
       #region Keys
      [Required(AllowEmptyStrings=false)]
      [StringLength(3)]
      public string GP_NATUREPIECEG { get; set;}
      [Required(AllowEmptyStrings = false)]
      [StringLength(3)]
      public string GP_SOUCHE { get; set; }
      [Required()]
      public int GP_NUMERO { get; set; }
      public int GP_INDICEG { get; set; }
       #endregion
    
       #region System
      public DateTime GP_DATECREATION { get; set; }
      public DateTime GP_HEURECREATION { get; set; }
      public DateTime GP_DATEMODIF { get; set; }
       #endregion
    
      public DateTime GP_DATEPIECE { get; set; }
    
      //public string GP_TIERS { get; set; } // come from EF Configuration
    
      #endregion
    
      #region Navigation
    
      public virtual gThirdParty ThirdParty { get; set; }
      public virtual gThirdParty ThirdPartyDelivered { get; set; }
      public virtual gThirdParty ThirdPartyCharged { get; set; }
      public virtual gThirdParty ThirdPartyPaying { get; set; }
      public virtual ICollection<gLine> Lines { 
       get { return _lines; } 
       set { _lines.Clear(); _lines.AddRange(value); }
      }
    
      #endregion
    
      #region Helpers
    
      public void AddLine (gLine gl, int pos = -1) {
       if ( pos < 0 )
        _lines.Add(gl);
       else
        _lines.Insert(pos, gl);
      }
    
      #endregion
    
      #region IValidatableObject Membres
    
      IEnumerable<ValidationResult> IValidatableObject.Validate (ValidationContext validationContext) {
       if ( GP_NUMERO <= 0 )
        yield return new ValidationResult(
         String.Format("gDocument cannot have this number [{0}]!", GP_NUMERO)
        );
       
       #region Default
       
       if ( GP_DATEPIECE == DateTime.MinValue ) {
        GP_DATEPIECE = DateTime.Now.Date;
       }
    
       if ( ThirdPartyCharged == null )
        ThirdPartyCharged = ThirdParty;
       if ( ThirdPartyDelivered == null )
        ThirdPartyDelivered = ThirdParty;
       if ( ThirdPartyPaying == null )
        ThirdPartyPaying = ThirdParty;
       
       #endregion
       
       #region System
       
       if ( GP_DATECREATION == DateTime.MinValue ) {
        GP_DATECREATION = DateTime.Now.Date;
        GP_HEURECREATION = DateTime.Now;
       }
       if ( GP_DATEMODIF == DateTime.MinValue ) {
        GP_DATEMODIF = DateTime.Now;
       }
       
       #endregion
      }
    
      #endregion
     }
    
    Do I have to consider to implement this business/integrity logic in another place ?
    Thank you in advance
     

    thierry
    Tuesday, August 23, 2011 9:13 PM

Answers

  • Hello,

    It is important to set validateAllProperties to false for this method to work. When validateAllProperties is false only properties with a [Required] attribute are checked. This allows the IValidatableObject.Validate() method handle the conditional validations. Please check this link for more information about Validate method. http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.ivalidatableobject.validate.aspx

    Hope this helps.

    Thanks,


    Larcolais Gong[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Larcolais Gong Wednesday, August 31, 2011 1:59 AM
    Saturday, August 27, 2011 1:32 PM
  • I assume that you are asking about IValidatableObject in context of DbContext API and validation in EntityFramework 4.1.

    I do think you should consider implement business logic in another place. In general my thinking is that the validation step shold not change your model. It should check if all the fields are set correctly and return validation errors if some of the are not set correctly. Having said that - it should be possible to make what you are trying to do work. If you change your model as part of validation you need to detect changes after the validation is complete and before changes are actually saved. You can do it in one of several ways:

    - The easiest but a bit cumbersome is just to call is to disable validation at all (by setting DbContextConfiguration.ValidateOnSaveEnabled to false) and call GetValidationErrors() manually before SaveChanges - this is a great way to prototype and to verify that changes you made during validation were actually detected and saved to the database

    - You can override SaveChanges() to do the work for you. In this case you would not have to call GetValidationErrors() before calling SaveChanges(). Instead you would call GetValidationErrors() from within overriden SaveChanges(). Again you need to disable validation since you don't want to invoke it twice. You would have to decide what to do if validation returns error - probably the best would be to throw the exception thrown by "regular" SaveChanges - DbEntityValidationException

    Pawel

    • Marked as answer by Larcolais Gong Wednesday, August 31, 2011 1:59 AM
    Monday, August 29, 2011 6:31 PM

All replies

  • Hello,

    It is important to set validateAllProperties to false for this method to work. When validateAllProperties is false only properties with a [Required] attribute are checked. This allows the IValidatableObject.Validate() method handle the conditional validations. Please check this link for more information about Validate method. http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.ivalidatableobject.validate.aspx

    Hope this helps.

    Thanks,


    Larcolais Gong[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Larcolais Gong Wednesday, August 31, 2011 1:59 AM
    Saturday, August 27, 2011 1:32 PM
  • I assume that you are asking about IValidatableObject in context of DbContext API and validation in EntityFramework 4.1.

    I do think you should consider implement business logic in another place. In general my thinking is that the validation step shold not change your model. It should check if all the fields are set correctly and return validation errors if some of the are not set correctly. Having said that - it should be possible to make what you are trying to do work. If you change your model as part of validation you need to detect changes after the validation is complete and before changes are actually saved. You can do it in one of several ways:

    - The easiest but a bit cumbersome is just to call is to disable validation at all (by setting DbContextConfiguration.ValidateOnSaveEnabled to false) and call GetValidationErrors() manually before SaveChanges - this is a great way to prototype and to verify that changes you made during validation were actually detected and saved to the database

    - You can override SaveChanges() to do the work for you. In this case you would not have to call GetValidationErrors() before calling SaveChanges(). Instead you would call GetValidationErrors() from within overriden SaveChanges(). Again you need to disable validation since you don't want to invoke it twice. You would have to decide what to do if validation returns error - probably the best would be to throw the exception thrown by "regular" SaveChanges - DbEntityValidationException

    Pawel

    • Marked as answer by Larcolais Gong Wednesday, August 31, 2011 1:59 AM
    Monday, August 29, 2011 6:31 PM