Exemple #1
0
        public static bool TryValidateModel <TModel>(IWebFormsView <TModel> wfView, XmlDataAnnotationsRuleSet ruleSet)
        {
            List <string>   errors       = new List <string>();
            IWFRuleProvider ruleProvider = new WFXmlRuleSetRuleProvider(ruleSet);

            return(WFUtilities.TryValidateModel(wfView.Model, "", new WFHttpContextValueProvider(HttpContext.Current), wfView.Html.MetaData, ruleProvider));
        }
Exemple #2
0
 public WFXmlRuleSetRuleProvider(string ruleSetName)
 {
     RuleSet          = WFUtilities.GetRuleSetForName(ruleSetName);
     ModelDisplayName = RuleSet.ModelDisplayName;
 }
Exemple #3
0
 public WFXmlRuleSetRuleProvider(XmlDataAnnotationsRuleSet ruleSet)
 {
     RuleSet = ruleSet;
 }
Exemple #4
0
        /// <summary>
        /// Load the specified XML file into memory as one or more XML rule sets in place of DataAnnotations.<br/>
        /// Use GetRuleSetForName() and GetRuleSetForType() to retrieve a rule set for validation.<br/>
        /// The WFXmlRuleSetRuleProvider class with the TryValidateModel() method.
        /// </summary>
        public static void RegisterXMLValidationConfiguration(string filename)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(filename);

            foreach (XmlNode node in doc.SelectNodes("validation/type"))
            {
                string assemblyName = node.Attributes["assemblyName"].Value;
                string name         = node.Attributes["name"].Value;
                foreach (XmlNode ruleSetNode in node.SelectNodes("ruleset"))
                {
                    XmlDataAnnotationsRuleSet ruleset = new XmlDataAnnotationsRuleSet();
                    try {
                        ruleset.ModelType = Type.GetType(name, true, true);
                    } catch (Exception ex) {
                        throw new Exception("Couldn't resolve model type " + name + ". You may need to specify the fully qualified assembly name in the 'name' field. ie: 'MyAssembly.MyClass, MyAssembly'");
                    }
                    ruleset.AssemblyName = assemblyName;
                    ruleset.TypeName     = name;
                    ruleset.Properties   = new List <XmlDataAnnotationsRuleSetProperty>();
                    ruleset.RuleSetName  = ruleSetNode.Attributes["name"].Value;

                    XmlAttribute rattr = ruleSetNode.Attributes["DisplayName"];
                    ruleset.ModelDisplayName = rattr == null ? ruleset.ModelDisplayName : rattr.Value;

                    XmlNode classAttsNode = ruleSetNode.SelectSingleNode("attributes");
                    if (classAttsNode != null)
                    {
                        ruleset.ClassValidators = new List <XmlDataAnnotationsValidator>();
                        foreach (XmlNode classAttr in classAttsNode.SelectNodes("validator"))
                        {
                            XmlDataAnnotationsValidator val = new XmlDataAnnotationsValidator();
                            foreach (XmlAttribute attr in classAttr.Attributes)
                            {
                                if (attr.Name.ToLower() == "negated")
                                {
                                    val.Negated = Boolean.Parse(attr.Value);
                                }
                                else if (attr.Name == "type")
                                {
                                    val.ValidatorTypeName = attr.Name;
                                    try {
                                        val.ValidatorType = Type.GetType(attr.Value, true, true);
                                    } catch (Exception ex) {
                                        throw new Exception("Couldn't resolve validator type " + attr.Value + ". You may need to specify the fully qualified assembly name in the 'type' field. ie: 'MyAssembly.MyClass, MyAssembly'");
                                    }
                                }
                                else
                                {
                                    val.ValidatorAttributes.Add(attr.Name, attr.Value);
                                }
                            }
                            ruleset.ClassValidators.Add(val);
                        }
                    }

                    foreach (XmlNode propertyNode in ruleSetNode.SelectNodes("properties/property"))
                    {
                        XmlDataAnnotationsRuleSetProperty prop = new XmlDataAnnotationsRuleSetProperty();
                        prop.ParentRuleSet = ruleset;
                        prop.PropertyName  = propertyNode.Attributes["name"].Value;

                        XmlAttribute xattr = propertyNode.Attributes["DisplayName"];
                        if (xattr != null)
                        {
                            prop.DisplayName = xattr.Value;
                        }

                        XmlAttribute rattrResource     = propertyNode.Attributes["DisplayNameResourceName"];
                        XmlAttribute rattrResourceType = propertyNode.Attributes["DisplayNameResourceType"];
                        if (rattrResource != null)
                        {
                            prop.DisplayNameResourceName = rattrResource.Value;
                        }
                        if (rattrResourceType != null)
                        {
                            try {
                                prop.DisplayNameResourceType = Type.GetType(rattrResourceType.Value, true, true);
                            } catch (Exception ex) {
                                throw new Exception("Couldn't resolve resource type " + rattrResourceType.Value + ". You may need to specify the fully qualified assembly name in the 'type' field. ie: 'MyAssembly.MyClass, MyAssembly'");
                            }
                        }

                        //Derive from propertyname if a display name was not found
                        if (xattr == null && rattrResource == null && rattrResourceType == null)
                        {
                            prop.DisplayName = prop.PropertyName;
                        }


                        prop.Validators = new List <XmlDataAnnotationsValidator>();
                        foreach (XmlNode validatorNode in propertyNode.SelectNodes("validator"))
                        {
                            XmlDataAnnotationsValidator validator = new XmlDataAnnotationsValidator();
                            validator.ParentProperty = prop;
                            foreach (XmlAttribute attr in validatorNode.Attributes)
                            {
                                if (attr.Name == "ErrorMessageResourceName")
                                {
                                    validator.ErrorMessageResourceName = attr.Value;
                                }
                                else if (attr.Name == "ErrorMessageResourceType")
                                {
                                    try {
                                        validator.ErrorMessageResourceType = Type.GetType(attr.Value, true, true);
                                    } catch (Exception ex) {
                                        throw new Exception("Couldn't resolve resource type " + attr.Value + ". You may need to specify the fully qualified assembly name in the 'type' field. ie: 'MyAssembly.MyClass, MyAssembly'");
                                    }
                                }
                                else if (attr.Name == "ErrorMessage")
                                {
                                    validator.ErrorMessage = attr.Value;
                                }
                                else if (attr.Name.ToLower() == "negated")
                                {
                                    validator.Negated = Boolean.Parse(attr.Value);
                                }
                                else if (attr.Name == "type")
                                {
                                    validator.ValidatorTypeName = attr.Name;
                                    if (attr.Value == "RequiredAttribute")
                                    {
                                        validator.ValidatorType = typeof(RequiredAttribute);
                                    }
                                    else if (attr.Value == "StringLengthAttribute")
                                    {
                                        validator.ValidatorType = typeof(StringLengthAttribute);
                                    }
                                    else if (attr.Value == "RegularExpressionAttribute")
                                    {
                                        validator.ValidatorType = typeof(RegularExpressionAttribute);
                                    }
                                    else if (attr.Value == "RangeAttribute")
                                    {
                                        validator.ValidatorType = typeof(RangeAttribute);
                                    }
                                    else
                                    {
                                        try {
                                            validator.ValidatorType = Type.GetType(attr.Value, true, true);
                                        } catch (Exception ex) {
                                            throw new Exception("Couldn't resolve validator type " + attr.Value + ". You may need to specify the fully qualified assembly name in the 'type' field. ie: 'MyAssembly.MyClass, MyAssembly'");
                                        }
                                    }
                                }
                                else
                                {
                                    validator.ValidatorAttributes.Add(attr.Name, attr.Value);
                                }
                            }

                            prop.Validators.Add(validator);
                        }
                        ruleset.Properties.Add(prop);
                    }
                    XmlRuleSets.Add(ruleset);
                }
            }
        }
Exemple #5
0
        protected override bool EvaluateIsValid()
        {
            _HasBeenChecked = true;
            if (String.IsNullOrEmpty(SourceTypeString))
            {
                if (SourceType == null &&
                    String.IsNullOrEmpty(XmlRuleSetName) &&
                    this.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\"\r\nFinally, the page can also implement IWFGetValidationRulesForPage.");
                }
                else if (SourceType == null &&
                         !String.IsNullOrEmpty(XmlRuleSetName))
                {
                    //Get the type from the XmlRuleSet
                    SourceType = WFUtilities.GetRuleSetForName(XmlRuleSetName).ModelType;
                }
                else if (SourceType == null && String.IsNullOrEmpty(XmlRuleSetName))
                {
                    SourceType = ((IWFGetValidationRulesForPage)this.Page).GetValidationClassType();
                }
            }
            else
            {
                try {
                    SourceType = Type.GetType(SourceTypeString, true, true);
                } catch (Exception ex) {
                    throw new Exception("Couldn't resolve type " + SourceTypeString + ". You may need to specify the fully qualified assembly name.");
                }
            }

            PropertyInfo prop = WFUtilities.GetTargetProperty(_propertyName, SourceType);

            Control validateControl = this.FindControl(this.ControlToValidate); //Search siblings

            if (validateControl == null)                                        //Search page
            {
                validateControl = WebControlUtilities.FindControlRecursive(this.Page, this.ControlToValidate);
            }
            string controlValue = WebControlUtilities.GetControlValue(validateControl);

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

                foreach (var attr in prop.GetCustomAttributes(typeof(ValidationAttribute), true).OfType <ValidationAttribute>())
                {
                    if (attr as IWFRequireValueProviderContext != null)
                    {
                        ((IWFRequireValueProviderContext)attr).SetValueProvider(new WFPageControlsValueProvider(this.Page, ""));
                    }

                    if (!attr.IsValid(controlValue))
                    {
                        this.ErrorMessage = attr.FormatErrorMessage(displayName);
                        return(false);
                    }
                }
                return(true);
            }
            else
            {
                XmlDataAnnotationsRuleSet         ruleset  = WFUtilities.GetRuleSetForType(SourceType, XmlRuleSetName);
                XmlDataAnnotationsRuleSetProperty property = ruleset.Properties.FirstOrDefault(p => p.PropertyName == PropertyName);
                if (property != null)
                {
                    foreach (XmlDataAnnotationsValidator val in property.Validators)
                    {
                        ValidationAttribute attr = WFUtilities.GetValidatorInstanceForXmlDataAnnotationsValidator(val);

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

                        if (!String.IsNullOrEmpty(ErrorMessage) &&
                            String.IsNullOrEmpty(attr.ErrorMessage))
                        {
                            attr.ErrorMessage = ErrorMessage;
                        }

                        foreach (var key in val.ValidatorAttributes.Keys)
                        {
                            PropertyInfo pi = attr.GetType().GetProperty(key);

                            string[] excludeProps = new string[] { };
                            if (attr.GetType() == typeof(StringLengthAttribute))
                            {
                                excludeProps = new string[] { "maximumLength" };
                            }
                            if (attr.GetType() == typeof(RangeAttribute))
                            {
                                excludeProps = new string[] { "minimum", "maximum" };
                            }
                            if (attr.GetType() == typeof(RegularExpressionAttribute))
                            {
                                excludeProps = new string[] { "pattern" };
                            }
                            if (!excludeProps.Contains(key))
                            {
                                pi.SetValue(attr, Convert.ChangeType(val.ValidatorAttributes[key], pi.PropertyType), null);
                            }
                        }
                        if (!attr.IsValid(controlValue))
                        {
                            this.ErrorMessage = attr.FormatErrorMessage(property.DisplayName ?? "");
                            return(false);
                        }
                    }
                }

                return(true);
            }
        }
Exemple #6
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);
        }