Language preference:

Phase 2 / DefaultValueAttribute

Here is one attribute that comes from the System.ComponentModel.DataAnnotations namespace, instead of from BLD. So don't put "DESDA." in when declaring it.

Use the DefaultValueAttribute to define the initial value for the DataField when in Insert mode (creating a record). As with many attributes, you can assign the default value at runtime by using the PeterBlum.DES.DataAnnotations.ICustomizeDataField interface on your Entity class.

Here are DefaultValueAttributes associated with the Order Entity class. It uses the ICustomizeDataField interface to assign today's date as the default for the OrderDate DataField.

[EntityDAOType(typeof(OrderDAO))]
[MetadataType(typeof(OrderMetadata))]
public partial class Order : DESDA.ICustomizeDataField
{
   public void CustomizeDataField(DESDA.ActiveDataField activeDataField)
   {
      if (activeDataField.DataEntryMode != DESDA.DataEntryMode.ReadOnly)
         switch (activeDataField.DataField)
         {
            case "OrderDate":
         // default value is today
               activeDataField.DefaultValue = DateTime.Today;
               break;
         }
   }
}

public class OrderMetadata
{
   [DefaultValue(1)] // UPS Standard shipping
   public object ShipVia { get; set; }
}

The Source Code Browser shows completed DataAnnotations. The DefaultValueAttributes have been highlighted.

In the next topic, you'll learn how to defend against hackers.



Open the Source Code Browser (C# only)
Source Code Browser
 
/* ------------------------------------------------
 * Describes the Entity class for: Order
 * Classes:
 *    Order - Entity class. Edit it for validation and to customize metadata at runtime
 *    OrderMetadata - Entity Metadata class. It contains the DataAnnotations.
 *    OrderDAO - BLD DataAccessObject format version of a Data Access Object.
 *    
 * Requires .net 4.0 and these references:
 *    System.ComponentModel.DataAnnotations
 *    PeterBlum.DES
 *    PeterBlum.DES.DataAnnotations
 * Generated: 7/8/2011 4:19:41 PM
 * ------------------------------------------------*/
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using PeterBlum.DES.DAO.Attributes;
using PeterBlum.DES.DAO.EntityDAO;
// Some members of this namespace have identical names to those in System.ComponentModel.DataAnnotations
// making it easy to switch from one to the other by adding the "DESDA." prefix
using DESDA = PeterBlum.DES.DataAnnotations;

namespace PeterBlum.WithDataAnnotations
{
   // --- ENTITY CLASS --------------------------------------------------
   /// <summary>
   /// Entity class. Edit it for validation and to customize metadata at runtime
   /// </summary>
   [EntityDAOType(typeof(OrderDAO))]
   [MetadataType(typeof(OrderMetadata))]
   public partial class Order : DESDA.ICustomizeDataField
   {
/// <summary>
/// Associated with the CustomValidationAttribute on the Order class,
/// this reports an error if the total price of the order exceeds OrderPriceLimit.
/// </summary>
/// <param name="pOrder"></param>
/// <param name="pValidationContext"></param>
/// <returns></returns>
      public ValidationResult CheckOrderLimit(Order pOrder, ValidationContext pValidationContext)
      {
       if (!AllowedOrderPriceTotal())
         return new DESDA.EntityValidationResult("CheckOrderLimit", // this is the Source parameter. It can be anything. It is used by the BLDPageManager.UpdateErrorMessage event. So make it useful for detecting this particular error
               String.Format("The order exceeds the limit of {0:C}.", OrderPriceLimit));
         return ValidationResult.Success;
      }

/// <summary>
/// Go through the Order details, totalling the OrderPrice column. If it exceeds 100,000.00,
/// the order is not allowed.
/// </summary>
/// <returns></returns>
      public bool AllowedOrderPriceTotal()
      {
         return ProductsTotal <= OrderPriceLimit;
      }

      [Browsable(false)]
      [DESDA.ScaffoldColumn(false)]
      public decimal OrderPriceLimit
      {
         get { return 1000000.0M; }
      }

      [DESDA.CurrencyDataType(ShowColumnTotal=true)]
      [DESDA.DisplayName("Products total", ShortDisplayName="Total")]
      public decimal ProductsTotal
      {
         get
         {
            decimal total = 0.0M;
            foreach (Order_Detail orderDetail in this.Order_Details)
               total = total + orderDetail.OrderPrice;
            return total;
         }
      }

      [DESDA.CurrencyDataType(ShowColumnTotal=true)]
      [DESDA.DisplayName("Products total with shipping charges", ShortDisplayName="Total w/ship")]
      public decimal ProductsTotalWithShipping
      {
         get
         {
            return ProductsTotal + (Freight.HasValue ? Freight.Value : 0.0M);
         }
      }


      #region ICustomizeDataField Members

      public void CustomizeDataField(DESDA.ActiveDataField activeDataField)
      {
         if (activeDataField.DataEntryMode != DESDA.DataEntryMode.ReadOnly)
            switch (activeDataField.DataField)
            {
               case "OrderDate":
            // OrderDate must be today's date or later in insert mode
                  if (activeDataField.DataEntryMode == DESDA.DataEntryMode.Insert)
                  {
                     DESDA.CompareToValueAttribute vCtoVAtt =
                        activeDataField.GetEditableValidationAttribute<DESDA.CompareToValueAttribute>(true);
                     vCtoVAtt.ValueToCompare = DateTime.Today;
                     vCtoVAtt.Operator = DES.ConditionOperator.GreaterThanEqual;
                     // default value is today
                     activeDataField.DefaultValue = DateTime.Today;
                  }
                  break;
            }
      }

      #endregion
   }  // class Order

   // --- ENTITY METADATA --------------------------------------------------
   /// <summary>
   /// Entity Metadata class.
   /// Companion to the Order Entity class that contains the DataAnnotations
   /// on properties with the same names as those in the actual Entity class.
   /// These properties do not require their types to match those in the Entity class.
   /// An Entity Metadata class allows the Entity class to be regenerated without
   /// overwriting DataAnnotations.
   /// </summary>
   [DESDA.CustomValidation(MethodName="CheckOrderLimit")]
   [DESDA.TableRestriction("Admin", DESDA.DenyAccess.None)]
   [DESDA.TableRestriction("Customer", DESDA.DenyAccess.Edit | DESDA.DenyAccess.Delete | DESDA.DenyAccess.Insert)]
   public class OrderMetadata
   {
      [DESDA.Required()]
      [DESDA.CharacterSet(LettersUppercase=true, LettersLowercase=false, ErrorMessage="Must be uppercase letters.")]
      [DESDA.StringLength(MinimumLength=5, MaximumLength=5, ErrorMessage="Exactly 5 letters.")]
      [DESDA.Filter(DESDA.AutoGeneratePriority.Always)]
      [DESDA.DisplayName("Customer ID", ShortDisplayName="Customer")]
      [DESDA.ScaffoldColumn(ScaffoldEdit=false, ScaffoldInsert=false)]
      public object CustomerID { get; set; }

      [DESDA.ScaffoldColumn(Position = 0)]  // make it appear first
      public object Customer { get; set;  }



      [DESDA.DateDataType()]
      [DESDA.Required()]
      [DESDA.DisplayName("Order date", ShortDisplayName="Ordered")]
      // Calculates Min Date and DefaultValue as Today's Date in Order.CustomizeDataField
     public object OrderDate { get; set; }
  
      [DESDA.DateDataType()]
      [DESDA.DisplayName("Required by")]
      [DESDA.CompareTwoColumns("OrderDate", DES.ConditionOperator.GreaterThanEqual)]
     public object RequiredDate { get; set; }
  
      [DESDA.DateDataType()]
      [DESDA.DisplayName("Date shipped", ShortDisplayName="Shipped")]
      [DESDA.CompareTwoColumns("OrderDate", DES.ConditionOperator.GreaterThanEqual)]
     public object ShippedDate { get; set; }
  
      [DESDA.Enumerated(ValueNameList="1=UPS Standard|2=UPS Overnight|3=UPS 2 day|10=FedEx Standard|11=FedEx Overnight")]
      [DefaultValue(1)] // UPS Standard shipping
     public object ShipVia { get; set; }
  
      [DESDA.CurrencyDataType(AllowNegatives=false)]
      [DESDA.DisplayName("Shipping charges")]
     public object Freight { get; set; }
  
      [DESDA.DisplayName("Recipient name")]
      [DESDA.Required()]
     public object ShipName { get; set; }
  
     [DESDA.Required()]
      [DESDA.RegularExpression(@"\S\s+\S", CaseInsensitive=true, 
         ErrorMessage="Enter a building number and street name.")] // requires at least one space between data, so we get a street and building number  
      [DESDA.Filter(AutoGeneratePriority=DESDA.AutoGeneratePriority.Advanced, InMultiFieldSearch=true)]
      [DESDA.DisplayName("Shipping Street", ShortDisplayName="Street")]
     public object ShipAddress { get; set; }

     [DESDA.Required()]
      [DESDA.Filter(AutoGeneratePriority=DESDA.AutoGeneratePriority.Advanced, InMultiFieldSearch=true)]
      [DESDA.DisplayName("Shipping City", ShortDisplayName="City")]
     public object ShipCity { get; set; }
  
      [DESDA.DisplayName("Shipping Region", ShortDisplayName="Region")]
     public object ShipRegion { get; set; }
  
     [DESDA.Required()]
      [DESDA.Filter(AutoGeneratePriority=DESDA.AutoGeneratePriority.Standard, InMultiFieldSearch=true)]
      [DESDA.DisplayName("Shipping Postal code", ShortDisplayName="Postal code")]
     public object ShipPostalCode { get; set; }
  
     [DESDA.Required()]
      [DESDA.EnumeratedString(ValueNameList="Brazil|Canada|France|Germany|Great Britain|Mexico|United States", DefaultValue="United States")]
      [DESDA.Filter(AutoGeneratePriority=DESDA.AutoGeneratePriority.Advanced, InMultiFieldSearch=true)]
      [DESDA.DisplayName("Shipping Country", ShortDisplayName="Country")]
     public object ShipCountry { get; set; }

      [DESDA.Filter(AutoGeneratePriority=DESDA.AutoGeneratePriority.Standard)]
      [DESDA.ForeignKeyQuery(DisplayDataFields="FullName")]
      public object Employee { get; set; }
   }  // class OrderMetadata

   // --- BLD DATAACCESSOBJECT  --------------------------------------------------
   /// <summary>
   /// BLD DataAccessObject class for the Order Entity class.
   /// It provides CRUD actions. The parent class already has default
   /// methods for Update(), Insert(), Delete() and several queries.
   /// </summary>
   /// <remarks>
   /// <para>For documentation, see the BLD DataAccessObject section of the Business Logic User's Guide.</para>
   /// </remarks>
   [TableName("Orders")]
   public class OrderDAO : LINQtoSQLEntityDAO<Order>
   {
      public OrderDAO() : base(typeof(NorthWindDataContext)) { }
      public OrderDAO(object pDataContext) : base(pDataContext) { }

      protected override void Update(LINQtoSQLEntityDAO<Order>.L2SChangeEntityActionWrapper pWrapper)
      {
   // NOTE: This is an example that doesn't really work. This process is handled 
   // by LinqToSql in the SET selector of Order.Customer.
   // Here order.Customer is always null.
         Order order = pWrapper.GetEntity();
         if (order.Customer != null)
            order.CustomerID = order.Customer.CustomerID;
         base.Update(pWrapper);
      }

      protected override void Insert(LINQtoSQLEntityDAO<Order>.L2SChangeEntityActionWrapper pWrapper)
      {
   // NOTE: This is an example that doesn't really work. This process is handled 
   // by LinqToSql in the SET selector of Order.Customer.
   // Here order.Customer is always null.
         Order order = pWrapper.GetEntity();
         if (order.Customer != null)
            order.CustomerID = order.Customer.CustomerID;
         base.Insert(pWrapper);
      }


   }  // class OrderDAO

}