Example #1
0
        /// <summary>
        /// Creates a &lt;span&gt; tag with appropriate validation information used by client side AND server side code.<br/>
        /// WFUtilities.FieldValidationErrorClass is applied if validation fails on a postback. This is used with an Html.&ltcontrol&gt;For() element.<br/>
        /// The property whose validation state is checked is derived from a strongly-typed lambda.
        /// </summary>
        /// <param name="ErrorMessage">(Optional) Override any ErrorMessage provided by resources/xml/validators with this property.</param>
        /// <param name="expression">An expression that identifies the property whose value will be rendered.<br/>
        /// ie: m => m.FirstName will render the 'FirstName' property.</param>
        /// <param name="htmlProperties">An anonymous object whose properties are applied to the element.<br/>
        /// ie: new { Class = "cssClass", onchange = "jsFunction()" } </param>
        /// <returns></returns>
        public string ValidationMessageFor <TProperty>(Expression <Func <TModel, TProperty> > expression, string ErrorMessage, object htmlProperties)
        {
            WFModelMetaProperty metaprop = null;
            ModelMetaData       mmd      = ModelMetaData.FromLambdaExpression(expression, _Model);
            HtmlTag             span     = new HtmlTag("span", new { id = mmd.PropertyName + "_validationMessage", name = mmd.PropertyName + "_validationMessage" });
            string lcName = mmd.PropertyName.ToLower();

            for (int i = 0; i < _MetaData.Properties.Count; i++)
            {
                if (_MetaData.Properties[i].MarkupName.ToLower() == lcName)
                {
                    metaprop = _MetaData.Properties[i];
                    break;
                }
            }
            if (metaprop != null)
            {
                if (metaprop.HasError)
                {
                    span.MergeObjectProperties(htmlProperties);
                    span.AddClass(WFUtilities.FieldValidationErrorClass);
                    if (String.IsNullOrEmpty(ErrorMessage))
                    {
                        span.InnerText = metaprop.Errors.FirstOrDefault() ?? "";
                    }
                    else
                    {
                        span.InnerText = ErrorMessage;
                    }
                    return(span.Render());
                }
            }

            span.MergeObjectProperties(htmlProperties);
            span.AddClass(WFUtilities.FieldValidationValidClass);

            span = PreProcess(span, _MetaData, TagTypes.ValidationMessage,
                              metaprop != null ? metaprop.MarkupName : mmd.PropertyName,
                              metaprop != null ? metaprop.PropertyName : mmd.PropertyName,
                              _Model);

            return(span.Render());
        }
Example #2
0
        /// <summary>
        /// Creates a &lt;span&gt; tag with appropriate validation information used by client side AND server side code.
        /// WFUtilities.FieldValidationErrorClass is applied if validation fails on a postback. This is used with an Html.&ltcontrol&gt;For() element.
        /// </summary>
        /// <param name="model">The model itself.</param>
        /// <param name="markupName">The markup name of the Html.&lt;control&gt;For() element.</param>
        /// <param name="propertyName">Must be the property name on the model object.</param>
        /// <param name="ErrorMessage">Override the error message (use with care)</param>
        /// <param name="htmlProperties">An anonymous object whose properties are applied to the element.<br/>
        /// ie: new { Class = "cssClass", onchange = "jsFunction()" } </param>
        /// <returns>Returns a span with WFUtilities.FieldValidationErrorClass or WFUtilities.FieldValidationValidClass as the class.</returns>
        public string ValidationMessageFor(object model, string markupName, string propertyName, string ErrorMessage, object htmlProperties)
        {
            WFModelMetaProperty metaprop = null;
            HtmlTag             span     = new HtmlTag("span", new { id = markupName + "_validationMessage", name = markupName + "_validationMessage" });

            string lcName = propertyName.ToLower();

            for (int i = 0; i < _MetaData.Properties.Count; i++)
            {
                //if (_MetaData.Properties[i].ModelObject == model && _MetaData.Properties[i].PropertyName.ToLower() == lcName)
                if (_MetaData.Properties[i].MarkupName.ToLower() == lcName)
                {
                    metaprop = _MetaData.Properties[i];
                    break;
                }
            }
            if (metaprop != null)
            {
                if (metaprop.HasError)
                {
                    span.MergeObjectProperties(htmlProperties);
                    span.AddClass(WFUtilities.FieldValidationErrorClass);

                    if (String.IsNullOrEmpty(ErrorMessage))
                    {
                        span.InnerText = metaprop.Errors.FirstOrDefault() ?? "";
                    }
                    else
                    {
                        span.InnerText = ErrorMessage;
                    }
                    return(span.Render());
                }
            }

            span.MergeObjectProperties(htmlProperties);
            span.AddClass(WFUtilities.FieldValidationValidClass);

            span = PreProcess(span, _MetaData, TagTypes.ValidationMessage, markupName, propertyName, model);

            return(span.Render());
        }
Example #3
0
        /// <summary>
        /// Returns the raw text of any generated server-side validation error for this property.<br/>
        /// This is useful if you want to override the default functionality that generates a &lt;span&gt; tag for validation error messages.
        /// </summary>
        /// <param name="expression">An expression that identifies the property whose value will be rendered.<br/>
        /// ie: m => m.FirstName will render the 'FirstName' property.</param>
        /// <returns></returns>
        public string TextValidationMessageFor <TProperty>(Expression <Func <TModel, TProperty> > expression)
        {
            WFModelMetaProperty metaprop = null;
            ModelMetaData       mmd      = ModelMetaData.FromLambdaExpression(expression, _Model);
            string lcName = mmd.PropertyName.ToLower();

            for (int i = 0; i < _MetaData.Properties.Count; i++)
            {
                if (_MetaData.Properties[i].MarkupName.ToLower() == lcName)
                {
                    metaprop = _MetaData.Properties[i];
                    break;
                }
            }
            if (metaprop != null)
            {
                if (metaprop.HasError)
                {
                    return(metaprop.Errors.FirstOrDefault() ?? "");
                }
            }
            return("");
        }
Example #4
0
        /// <summary>
        /// Root TryValidateModel() method. Returns false if any validation errors are found.
        /// </summary>
        /// <param name="model">A pointer to the current model object</param>
        /// <param name="prefix">Optional. A prefix to search and filter values from the value provider.</param>
        /// <param name="values">A class implementing IWFValueProvider (examples include WFObjectValueProvider and WFHttpContextValueProvider)</param>
        /// <param name="metadata">Optional. Required to collect error data or show error markup on a page. The current WFModelMetaData object.</param>
        /// <param name="ruleProvider">A class implementing IWFRuleProvider (examples include WFTypeRuleProvider and WFXmlRuleSetRuleProvider).<br/>
        /// This object provides the rules (ie: DataAnnotations) that needed to be validated, and which properties to validate them against.<br/>
        /// All other properties are ignored.</param>
        /// <returns>Returns false if any validation errors were found.</returns>
        public static bool TryValidateModel(object model, string prefix, IWFValueProvider values, WFModelMetaData metadata, IWFRuleProvider ruleProvider)
        {
            bool validated = true;

            //Make sure we have metadata
            metadata        = metadata == null ? metadata = new WFModelMetaData() : metadata;
            metadata.Errors = new List <string>();

            //Create a rule provider if one was not provided. WFTypeRuleProvider will handle [MetadataType]
            ruleProvider = ruleProvider == null ? new WFTypeRuleProvider(model) : ruleProvider;

            validated = validateModelAttributes(model, ruleProvider.GetClassValidationAttributes(), metadata.Errors, ruleProvider.ModelDisplayName);

            if (metadata.Errors.Count > 0)
            {
                validated = false;
            }

            foreach (PropertyInfo pi in ruleProvider.GetProperties())
            {
                if (values.ContainsKey(prefix + pi.Name))
                {
                    WFModelMetaProperty metaprop = null;
                    foreach (ValidationAttribute attr in ruleProvider.GetPropertyValidationAttributes(pi.Name))
                    {
                        if (attr as IWFRequireValueProviderContext != null)
                        {
                            ((IWFRequireValueProviderContext)attr).SetValueProvider(values);
                        }

                        string displayName = ruleProvider.GetDisplayNameForProperty(pi.Name);
                        bool   isValid     = false;
                        if (attr.GetType() == typeof(RangeAttribute))
                        {
                            try { isValid = attr.IsValid(values.KeyValue(prefix + pi.Name)); } catch (Exception ex) {
                                if (ex.GetType() == typeof(FormatException))
                                {
                                    isValid = false;
                                }
                                else
                                {
                                    throw ex;
                                }
                            }
                        }
                        else
                        {
                            isValid = attr.IsValid(values.KeyValue(prefix + pi.Name));
                        }

                        if (!isValid)
                        {
                            validated = false;
                            metadata.Errors.Add(attr.FormatErrorMessage(displayName));

                            if (metaprop == null) // Try to find it ...
                            {
                                foreach (WFModelMetaProperty mx in metadata.Properties)
                                {
                                    if (mx.ModelObject == model && pi.Name.ToLower() == mx.PropertyName.ToLower())
                                    {
                                        metaprop = mx;
                                        break;
                                    }
                                }
                            }
                            if (metaprop == null) // Make a new one ...
                            {
                                metaprop              = new WFModelMetaProperty();
                                metaprop.ModelObject  = model;
                                metaprop.PropertyName = pi.Name;
                                metaprop.DisplayName  = displayName;
                                metaprop.MarkupName   = prefix + pi.Name;
                                metaprop.ValidationAttributes.Add(attr);

                                metadata.Properties.Add(metaprop);
                            }
                            metaprop.HasError = true;
                            metaprop.Errors.Add(attr.FormatErrorMessage(displayName));
                        }
                    }
                }
            }
            return(validated);
        }
Example #5
0
        /// <summary>
        /// Find or create a WFModelMetaProperty for the DataAnnotationValidatorControl.
        /// The WFModelMetaProperty will be added to the WFModelMetaData object.
        /// </summary>
        /// <param name="dvc">The DataAnnotationValidatorControl whose property needs to be added to metadata.</param>
        /// <param name="metadata">The existing metadata to search through.</param>
        /// <returns></returns>
        public static WFModelMetaProperty GetMetaPropertyFromValidator(Control rootControl, DataAnnotationValidatorControl dvc,
                                                                       WFModelMetaData metadata)
        {
            Type                sourceType        = dvc.SourceType;
            Control             controlValidating = WebControlUtilities.FindControlRecursive(rootControl, dvc.ControlToValidate);
            WFModelMetaProperty metaproperty      = metadata.Properties.FirstOrDefault(m => m.MarkupName == controlValidating.UniqueID);

            if (metaproperty == null)
            {
                metaproperty = new WFModelMetaProperty();
                metadata.Properties.Add(metaproperty);
            }

            metaproperty.PropertyName = dvc.PropertyName;
            metaproperty.MarkupName   = controlValidating.UniqueID;

            if (String.IsNullOrEmpty(dvc.SourceTypeString))
            {
                if (sourceType == null &&
                    String.IsNullOrEmpty(dvc.XmlRuleSetName) &&
                    dvc.Page as IWFGetValidationRulesForPage == null)
                {
                    throw new Exception("The SourceType and SourceTypeString properties are null/empty on one of the validator controls.\r\nPopulate either property.\r\nie: control.SourceType = typeof(Widget); OR in markup SourceTypeString=\"Assembly.Classes.Widget, Assembly\"");
                }
                else if (sourceType == null && !String.IsNullOrEmpty(dvc.XmlRuleSetName))
                {
                    sourceType = WFUtilities.GetRuleSetForName(dvc.XmlRuleSetName).ModelType;
                }
                else if (sourceType == null && String.IsNullOrEmpty(dvc.XmlRuleSetName))
                {
                    sourceType = ((IWFGetValidationRulesForPage)dvc.Page).GetValidationClassType();
                }
            }
            else
            {
                try {
                    sourceType = Type.GetType(dvc.SourceTypeString, true, true);
                } catch (Exception ex) {
                    throw new Exception("Couldn't resolve type " + dvc.SourceTypeString + ". You may need to specify the fully qualified assembly name.");
                }
            }

            PropertyInfo prop = WFUtilities.GetTargetProperty(dvc.PropertyName, sourceType);

            if (String.IsNullOrEmpty(dvc.XmlRuleSetName))
            {
                foreach (var attr in prop.GetCustomAttributes(typeof(ValidationAttribute), true).OfType <ValidationAttribute>())
                {
                    var    displayNameAttr = prop.GetCustomAttributes(typeof(DisplayNameAttribute), true).OfType <DisplayNameAttribute>().FirstOrDefault();
                    string displayName     = displayNameAttr == null ? prop.Name : displayNameAttr.DisplayName;

                    if (attr as IWFRequireValueProviderContext != null)
                    {
                        ((IWFRequireValueProviderContext)attr).SetValueProvider(new WFPageControlsValueProvider(dvc.Page, ""));
                    }

                    metaproperty.DisplayName = displayName;
                    metaproperty.ValidationAttributes.Add(attr);
                    if (!attr.IsValid(GetControlValue(controlValidating)))
                    {
                        metaproperty.HasError = true;
                        if (metaproperty.Errors == null)
                        {
                            metaproperty.Errors = new List <string>();
                        }
                        metaproperty.Errors.Add(attr.FormatErrorMessage(displayName));
                    }
                }
            }
            else
            {
                XmlDataAnnotationsRuleSet ruleset = WFUtilities.GetRuleSetForType(sourceType, dvc.XmlRuleSetName);
                metaproperty.DisplayName = dvc.PropertyName;
                try {
                    //It's OK to have a DataAnnotationValidatorControl for a property that has no validation rules
                    //defined in the XML.
                    XmlDataAnnotationsRuleSetProperty property = ruleset.Properties.FirstOrDefault(p => p.PropertyName == dvc.PropertyName);
                    if (property != null)
                    {
                        foreach (var validator in property.Validators)
                        {
                            ValidationAttribute attr = WFUtilities.GetValidatorInstanceForXmlDataAnnotationsValidator(validator);

                            if (attr as IWFRequireValueProviderContext != null)
                            {
                                ((IWFRequireValueProviderContext)attr).SetValueProvider(new WFPageControlsValueProvider(dvc.Page, ""));
                            }

                            foreach (var key in validator.ValidatorAttributes.Keys)
                            {
                                PropertyInfo pi = attr.GetType().GetProperty(key);
                                if (pi != null)
                                {
                                    pi.SetValue(attr, Convert.ChangeType(validator.ValidatorAttributes[key], pi.PropertyType), null);
                                }
                            }
                            metaproperty.ValidationAttributes.Add(attr);
                            if (!attr.IsValid(GetControlValue(controlValidating)))
                            {
                                metaproperty.HasError = true;
                                if (metaproperty.Errors == null)
                                {
                                    metaproperty.Errors = new List <string>();
                                }
                                metaproperty.Errors.Add(validator.ErrorMessage);
                            }
                        }
                    }
                } catch (Exception ex) {
                    throw new Exception("Error trying to validate " + dvc.PropertyName + ", innerexception may have more details...\r\nMake sure ErrorMessage isn't specified in more than one place.", ex);
                }
            }
            return(metaproperty);
        }