Data Annotations

Data annotations are defined in the namespace MvcControlsToolkit.DataAnnotations.

CanSortAttribute .  It can decorate properties of a View Model. It declares that a property can be used for user specified sorting and filtering. The EnableSortingFor and DataFilterClauseFor helpers  just cancel sorting and filtering requirements on properties that are not decorated with the CanSortAttribute. The CanSortAttribute has two properties Allow and Deny. Only filtering operations listed in Allow but not listed in Deny will be accepted. Both Allow and Deny accept the bitwise or of items from the enumeration: MVCControlsToolkit.Linq.FilterCondition. Their default values are:

 

            Allow = FilterCondition.Equal |
                FilterCondition.LessThan |
                FilterCondition.LessThanOrEqual |
                FilterCondition.GreaterThan |
                FilterCondition.GreaterThanOrEqual |
                FilterCondition.NotEqual |
                FilterCondition.StartsWith |
                FilterCondition.EndsWith |
                FilterCondition.IsContainedIn |
                FilterCondition.Contains;
            Deny = FilterCondition.IsContainedIn |
                FilterCondition.Contains;

 

The methods:

 

public static FilterCondition AllowedForProperty(Type type, string propertyName)

public static FilterCondition AllowedForProperty<T, F>(Expression<Func<T, F>> field)

 

rerturn the operations allowed on a given property of a given class.

While the methods:

 

public static FilterCondition AllowedForProperty(FilterCondition conditions, Type type, string propertyName)

public static FilterCondition AllowedForProperty<T, F>(FilterCondition conditions, Expression<Func<T, F>> field)

intersects a set of given operations with the set of allowed operations.

 

FormatAttribute . It inherits from the

DisplayFormat .Net attribute, and has mainly its same functions. The only difference being that it has three more string properties: Prefix, Postfix, and  ClientFormat. The ClientFormat string specifies a formatting rules to be applied on the client. The sintax of the client formatting rules is defined here: https://github.com/jquery/globalize. In addition to the standard formats listed there we added also the "G" date format, since it is the default date format used in .Net. The others two strings are then chained before and after the result of the previous step. If the values are rendered with the TypedTextBox or TypedTextBoxFor helper, when the user edit the field both Prefix and Postfix strings disappear and the ClientFormat appears in a simplified version, and everything reappear as before at the end of the editing. In case the input field is empty they are absent too, and a WaterMark is displayed. The Prefix, Postfix, and  ClientFormat are available in the MetaData AdditionalValues property with the names: MVCControlsToolkit.ClientFormatString, MVCControlsToolkit.ClientFormatPrefix, MVCControlsToolkit.ClientFormatPostfix. If the above properties are not defined and the ExtractClientFormat is set to true they will be extracted automatically from the server side format string. Prefix and Postfix can be also stored in a resource file to allow their localization by using the constructor: public FormatAttribute(Type resourceType, string prefixKey, string postfixKey). When the ClientFormat property has not been provided, if the property ExtractClientFormat is true the client format is extracted from the DateFormat property inherited from the  DisplayFormat attribute. This might cause javascript errors if the server side format is not supported by the client side globalization library.

MileStoneAttribute. It can decorate properties of a View Model and has no properties and no parameters. It just declares that the property must not be displayed in edit mode but that it should be used to give hints or constraints to a user input. DynamicMinimum and DynamicMaximum such as the ones used with the DateRangeAttribute might be decorated with this attribute if one don't want the user be able to change them on the client side. When input controls capable of enforcing DynamicMaximum and DynamicMinimum immediately on the client side see this attribute they decide a fixed value for this constraints once and for all on the server side when the control is rendered, and then use them on the client side.  On the contrary, if no such attribute is found the control expects the DynamicMaximum and DynamicMinimum be available on the client side in some input field and that they might be changed by the user. If the values are not rendered with controls capable of enforcing automatically DynamicMinimum and DynamicMaximum  on the client side the MileStone attribute gives to the View designer, the hint to display adequate messages to drive the user.

DateRangeAttribute.  One can apply more than a DataRange attribute to each DateTime property. Each of them can specify both  static Minimum and Maximum(called SMaximum and SMinimum) and dynamic Minimum and Maximum(called DynamicMinimum and DynamicMaximum).

SMaximum and SMinimum may set either to a string representing a date in international format, or to a date spefified through an offset relative to "Now" or "Today", The syntax of th string is as follows:

 

SMinimum="Now-1h+3d..." or SMinimum="Today+1h-3d..." 
where:
  • s: seconds
  • m: minutes
  • h: hours
  • d:days
  • M: moths
  • y: years
  • T: it comes without any number before. It takes a value from HttpContext.Current.Items["CurrentTimeShift"] and add or subtract it. The value here must me an integer that is interpreted as a number of hours. The developer can use it to handle timeline difference between client and server. The value in HttpContext.Current.Items["CurrentTimeShift"] can be taken from the user preferences or a cookie or autodetected from the browser (at least one post is needed to perform autodetect).
  • t: tolerance on the server. Tolerance in minutes, that is used to validate the constraints on the server. It is needed to take into account difference between the server and client clocks, but Mainly  the time delay due to the computation+user processing time. Without this tolerance a date might be validated succesfully on the client but might fail on the server.

For a concrete example of use of the SMinimum and SMaximum see this tutorial where they are used together with a DataGrid.

The property C  to be used as either dynamic maximum or as dynamic Minimum for a property X  is defined with a string containing the dot separated list of properties to reach C from the father object of X(the object where the property X is defined).

The value of C will be used both to do server side validation and to force the possible choices of the DropDowns of X on the client side. If C is rendered in the View as an input field, the values inserted by the user for C  will be used to constrain the possible input for X directly on the client side.

Delays can be applied to both dynamic minima and dynamic maxima in the DateRange attribute. For instance, one can requires X be 5 days before C. What Happens on client side when a constraint is violated depends on the value of the RangeType property of the DateRange attribute: 

 

  1. X has RangeType set to Verify and C is not rendered as an input field and it is decorated with the MileStone attribute. The value of X is forced to conform with the constraint imposed by C.
  2. X has RangeType set to Verify and C is  rendered as an input field and
  3.  
  4. it is not decorated with the MileStone attribute. The value of X is forced to conform to the constraint imposed by the value of C. When the user changes the value of C, the change is immediately reflected both on the value of X and on the possible choices in the DropDowns of X, specifically: the value of X will be possibly changed to satisfy the constraint imposed by C, and the DropDownsof X will only allow values compatible with such a constraint.
  5. X has RangeType set to Propagate and C is  rendered as an input field and has a  simmetric DateRange attribute with a TargetType set to Propagate .  When the user changes the value of one of them the value of the other changes atuomatically to conform with the constraint. For instance, suppose you have an activity whose minimum duration is one week. By using a RangeType of Propagate for both the start and the end date of the activity and a delay of one week, the user can change both dates freely but when it do a change to one of them the other date is changed to enforce the one week minimum duration constraint.

The MileStone attribute declares that a property has been inserted in the Vie Model just to drive the user to insert an input confroming with some constraints, and that its value will not be rendered as an input fileld.

Delays can be specified either as static TimeSpans or dynamically, however in any case changes in their values on the client side are not supported(it makes no sense to allow the user to change the delay).

It is worth to point out that each property may have several DateRange attributes. Thus, complex network of constraints can be handled on the client side(be careful to avoid circular dependencies and inconsistent constraints).

Caution need to be taken when verifying dynamic constraints on the server side, because the sensible data defining the constraint (that maybe either a dynamic delay or a dynamic minimum or maximum) cannot be taken from the model extracted by the data posted back by the user. Data coming from the client side are always to be considered unreliable because of  both malicious users or simple errors. Therefore validation need to be performed or repeated after having retrived these sensible data from a data store.

For a concrete example of use of the DynamicMinimum and DynamicMaximum see this tutorial where they are used together with a DataGrid.

DynamicRangeAttribute .  On the server side acts exactly in the same way as the DateRangeAttribute (see above) but with numeric types. On the client side constraints are not propagated automatically as in the case of the DateRangeAttribute but use the standard client validation mechanism based on error signalling.

RequiredFieldsAttribute .  Object level validation attribute that controls all required fields of an object. The required fields are listed in the Fields property of the attribute as a comma separated list of field names. Fields to be cotrolled can be specified also in object contained as properties of the root object, for instance PersonalInfos.Name  stands for the Name property of the object contained in the PersonalInfos properties of the root object. Being a class level attribute it can be applied directly on an entity class, thus allowing the use of a single metaclass for both the business(or entity ) class and all related ViewModels, since all other property level constraints applies wherever the involved property is used. Since it is not intended for being automatically controlled by the MVC engine it can be verified with the help of the static methods of the Validator class. If the RejectEmptyIEnumerables parameter of the attribute is set to true, the attribute triggers also when a property is an empty collection.

Last edited Jun 22 at 11:59 AM by frankabbruzzese, version 16

Comments

No comments yet.