Improving Business rules
Back
An Attribute allows the programmer to annotate a class or property with "metadata".
Within ASP.NET Dynamic Data, Attributes annotate the classes that describe your
tables with your business rules and some user interface elements.
Data types
DES introduces more data types. For example, the Measurement data type is for any
type of measurement, like gallons, inches, decibels, etc.
Features of DES's extended Data type support:
- There are new DataTypeAttributes specific to a datatype, such as TimeOfDayDataTypeAttribute.
These also define a default FieldTemplate and a validation rule.
- Many DataTypeAttributes have additional parameters to further customize them, such
as the terminology used on the MeasurementDataTypeAttributes or the file extensions
supported when selecting an image file.
[DES.CurrencyDataType(AllowNegatives=false,
UseCurrencySymbol=true,
MaxWholeDigits=4)]
public object UnitPrice { get;
set; }
[DES.DateDataType(ErrorMessage="This is an error",
SummaryErrorMessage="The {LABEL1} is an illegal
date.",
DisplayOrder=0)]
public object BirthDate { get;
set; }
- The DES.EnumeratedAttribute and DES.EnumeratedStringAttribute introduce support
for enumerated types on integer and string columns. You supply a list of names shown
the users that map to specific values.
For integer fields, those names can come from an actual enumerated type.
[DES.EnumeratedAttribute(EnumeratedType=typeof(MyNamespace.OutputMode)]
public object OutputMode { get;
set; }
|
DataTypeAttribute
|
Description
|
FieldTemplate
|
DES.DateDataTypeAttribute
|
Dates
|
"Date"
|
DES.TimeOfDayDataTypeAttribute
|
Time of day
|
"Time"
|
DES.DurationDataTypeAttribute
|
Durations
|
"Duration"
|
DES.AnniversaryDataTypeAttribute
|
Dates showing month and date, but no year.
|
"Anniversary"
|
DES.MonthYearDataTypeAttribute
|
Dates showing month and year, but no date.
|
"MonthYear"
|
DES.IntegerDataTypeAttribute
|
Integers
|
"Integer"
|
DES.DecimalDataTypeAttribute
|
Floating point numbers
|
"Decimal"
|
DES.CurrencyDataTypeAttribute
|
Currency numbers
|
"Currency"
|
DES.PercentDataTypeAttribute
|
Numbers representing percentages
|
"Percent"
|
DES.IntegerMeasurement-
DataTypeAttribute
|
Integers representing measurements. Includes labels to describe the measurement
units.
|
"Measurement"
|
DES.DecimalMeasurement-
DataTypeAttribute
|
Floating point numbers representing measurements. Includes labels to describe the
measurement units.
|
"Measurement"
|
|
Validation
There are ValidationAttributes for many validators within the DES Validation framework.
Validating data types often requires more rules that just "test that it is a [name
your type] value". For example, currencies may not allow negative numbers or a decimal
field should never have more than 3 decimal places. DES's validators already know
about these extra rules. The DES-supplied ValidationAttributes let the database
developer dictate them.
The native ASP.NET Validation framework cannot apply its predefined validators to
columns in different naming containers. FieldTemplates are separate naming containers.
So the CompareValidator cannot be setup to compare two columns. The DES implementation
fully supports multiple column validation through its new ValidationAttributes for
CompareTwoFields, Difference and more.
[DES.Required(DisplayOrder=1)]
[DES.Range("1900-01-01", "1999-12-31",
DisplayOrder=5)]
[DES.DateDataType(ErrorMessage="This is an error",
SummaryErrorMessage="The {LABEL1} is an illegal
date.",
DisplayOrder=0)]
[DES.CompareTwoColumns("HireDate",
PeterBlum.DES.ConditionOperator.LessThan, DisplayOrder=10)]
public object BirthDate { get;
set; }
[DES.DateDataType(ErrorMessage="This is an error",
SummaryErrorMessage="The {LABEL1} is an illegal
date.")]
public object HireDate { get;
set; }
When defining validators, sometimes they need to be created based on live data.
DES lets you create a ValidationAttribute based on that row by implementing the
ICustomizeColumn interface in the Table's class or IUICustomizeColumn interface
on the Master Page.
|
ValidationAttribute Type
|
DES Validator it creates
|
DES.RequiredAttribute
|
RequiredTextValidator or RequiredSelectionValidator depending on the data entry
control used by the FieldTemplate
|
DES.RangeAttribute
|
RangeValidator
|
DES.CompareToValueAttribute
|
CompareToValueValidator
|
DES.RegularExpressionAttribute
|
RegExValidator
|
DES.StringLengthAttribute
|
TextLengthValidator
|
DES.CompareTwoColumnsAttribute
|
CompareTwoFieldsValidator
|
DES.DifferenceAttribute
|
DifferenceValidator
|
DES.StringListAttribute
|
CompareToStringsValidator
|
DES.InjectionSecurityAttribute
|
FieldSecurityValidator
|
DES.CharacterSetAttribute
|
CharacterValidator
Note: FieldTemplates also apply this to their FilteredTextBox controls.
|
DES.DateDataTypeAttribute,
DES.TimeOfDayDataTypeAttribute,
DES.DurationDataTypeAttribute,
DES.AnniversaryDataTypeAttribute,
DES.MonthYearDataTypeAttribute,
DES.IntegerDataTypeAttribute,
DES.DecimalDataTypeAttribute,
DES.CurrencyDataTypeAttribute,
DES.PercentDataTypeAttribute,
DES.IntegerMeasurement-
DataTypeAttribute,
DES.DecimalMeasurement-
DataTypeAttribute
|
DataTypeCheckValidator with its DataType set appropriately.
|
DES.EmailAddressAttribute
|
EmailAddressValidator
|
DES.CreditCardNumberAttribute
|
CreditCardNumberValidator
|
DES.ABARoutingNumberAttribute
|
ABARoutingNumberValidator
|
|
Column dependencies
DES introduces the "DependencyAttribute". Apply it to columns where another column
determines if this column is active or not. For example, a date column may not be
available until a boolean column (represented by a checkbox) is true (checked).
The dependency has two effects on the user interface. It disables (or hides) the
data entry control and it disables its associated validators.
public object CategoryName
{ get; set; }
[DES.RequiredDependency("CategoryName")]
public object Description {
get; set; }
Character sets for textual columns
The table's metadata can identify a character set for a textual column by using
the DES.CharacterSetAttribute. The FieldTemplates will adapt to that characterset,
filtering out illegal characters as they are typed.
[DES.CharacterSet(LettersUppercase=false,
LettersLowercase=false, Digits=true,
Space=true, OtherCharacters="-()")]
public object PhoneNumber {
get; set; }
Scaffolding rules
The ScaffoldColumnAttribute has been expanded to support repositioning the column
in two ways:
- Relative to the current position
- After a specific column name
The Automatic Scaffolding engine (an implementation of the System.Web.UI.IAutoFieldGenerator
interface) has been rewritten to handle far more than just the improved ScaffoldColumnAttribute.
The Page Developer to include the IFieldGeneratorGuidance interface to programmatically
specify the desired list of data fields and supporting rules for total control,
and to avoid creating duplicate web forms when the only change is in the data field
list.
void DES.IFieldGeneratorGuidance<DES.DataFieldInPattern,
DES.BaseItemInPattern>.BeforeGeneration(
DES.FieldGenerationArgs<DES.DataFieldInPattern, DES.BaseItemInPattern>
pArgs)
{
if ((pArgs.TableName ==
"Employees") && (pArgs.DataControlAction == DES.DataControlAction.List))
{
pArgs.ShowLongStringsInLists = true;
pArgs.AddColumn("FirstName");
pArgs.AddField(new DES.DataFieldInPattern("LastName",
-1));
pArgs.AddColumn("BirthDate");
pArgs.AddColumn("PhotoPath");
}
}
void DES.IFieldGeneratorGuidance<DES.DataFieldInPattern,
DES.BaseItemInPattern>.AfterGeneration(
DES.FieldGenerationArgs<DES.DataFieldInPattern, DES.BaseItemInPattern>
pArgs)
{
if ((pArgs.TableName ==
"Employees") && (pArgs.DataControlAction == DES.DataControlAction.Details))
{
pArgs.HideFieldByColumnName("Employees");
pArgs.HideFieldByColumnName("Orders");
}
}
Sub BeforeGeneration(ByVal pArgs As DES.FieldGenerationArgs(Of DES.DataFieldInPattern, DES.BaseItemInPattern)) _
Implements DES.IPatternTemplateFieldGeneratorGuidance.BeforeGeneration
If (pArgs.TableName = "Employees")
And (pArgs.DataControlAction = DES.DataControlAction.List)
Then
pArgs.ShowLongStringsInLists = True
pArgs.AddColumn("FirstName")
pArgs.AddField(new DES.DataFieldInPattern("LastName",
-1))
pArgs.AddColumn("BirthDate")
pArgs.AddColumn("PhotoPath")
End If
End Sub
Sub AfterGeneration(ByVal
pArgs As DES.FieldGenerationArgs(Of
DES.DataFieldInPattern, DES.BaseItemInPattern))_
Implements DES.IPatternTemplateFieldGeneratorGuidance.AfterGeneration
If (pArgs.TableName = "Employees")
And (pArgs.DataControlAction = DES.DataControlAction.Details)
Then
pArgs.HideFieldByColumnName("Employees")
pArgs.HideFieldByColumnName("Orders")
End If
End Sub
More Attributes
- UIHintAttribute - Determines which FieldTemplate to use. Expanded to allow setting
the FieldTemplate ("UIHint") and properties on that FieldTemplate based on the mode
(readonly, edit, insert).
- DisplayNameAttribute - Assigns the name of the data field shown to the user. Expanded
to support DES's String Lookup Manager for localization.
- DescriptionAttribute - A description shown through hints or tooltips in FieldTemplates.
Expanded to support DES's String Lookup Manager for localization.
- CacheListAttribute - When the FieldTemplate uses a ListBox or DropDownList to show
items of an Enumerated type or ForeignKey, use this to cache the list.
- SortableColumnAttribute - Determines if the column should support sorting user
interfaces and its Sort Expression. Columns determine sorting without it based on
their datatype. Use this to override that default.
Changing attribute values at the page level
Attributes are retrieved as the MetaColumn objects are created, which only happens
once per application start. Once established, they are unchangable. Yet they have
properties that you may want to edit while building the page such as IsRequired,
IsReadOnly, DefaultValue, MaxLength, and the ValidationAttributes.
Being global data, the MetaColumn class must never be edited by page-level code.
DES resolves this by offering the ModifiableColumn property on each FieldTemplate.
It contains a copy of the attribute values that you can edit at the page-level by
implementing the ICustomizeColumn or IUICustomizeColumn interfaces.
Back
|