예제 #1
0
        /// <summary>
        /// Load meta data and update the UI.
        /// </summary>
        /// <param name="forceUpdate">If true, metadata will not be loaded from cache.</param>
        private void LoadMetadata(bool forceUpdate)
        {
            ValidationMetadata vmd               = null;
            object             entity            = null;
            BindingExpression  bindingExpression = null;

            if (!String.IsNullOrEmpty(this.PropertyPath))
            {
                entity = this.DataContext;
                // Pull metadata directly from the DataContext.  This isn't cached so it will be pulled every time.
                vmd = ValidationHelper.ParseMetadata(this.PropertyPath, entity);
            }
            else if (this.Target != null)
            {
                // Pull the metadata from the target FrameworkElement.
                vmd = ValidationHelper.ParseMetadata(this.Target, forceUpdate, out entity, out bindingExpression);
            }
            if (this.ValidationMetadata != vmd)
            {
                this.ValidationMetadata = vmd;
                // Update to the new VMD
                if (!this._descriptionOverridden)
                {
                    string description = null;
                    if (this.ValidationMetadata != null)
                    {
                        description = this.ValidationMetadata.Description;
                    }
                    SetValue(DescriptionProperty, description);
                }
            }
        }
 public void Configure(ValidationMetadata metadata)
 {
     foreach (var action in _validationActions)
     {
         action(metadata);
     }
 }
예제 #3
0
        /// <summary>
        /// Parse metadata from a target FrameworkElement.  This will cache the metadata on the element as an attached property.
        /// </summary>
        /// <param name="element">The target FrameworkElement to pull metadata from.</param>
        /// <param name="forceUpdate">If set, will not pull metadata from cache.</param>
        /// <param name="entity">The entity used.</param>
        /// <param name="bindingExpression">The bindingExpression used.</param>
        /// <returns>Returns the metadata associated with the element.  Will be null if no metadata was found.</returns>
        internal static ValidationMetadata ParseMetadata(FrameworkElement element, bool forceUpdate, out object entity, out BindingExpression bindingExpression)
        {
            entity            = null;
            bindingExpression = null;
            if (element == null)
            {
                return(null);
            }

            if (!forceUpdate)
            {
                ValidationMetadata existingVMD = element.GetValue(ValidationMetadataProperty) as ValidationMetadata;
                if (existingVMD != null)
                {
                    return(existingVMD);
                }
            }

            BindingExpression be = null;

            FieldInfo[] fields = element.GetType().GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
            foreach (FieldInfo field in fields)
            {
                if (field.FieldType == typeof(DependencyProperty))
                {
                    // Found a dependency property
                    be = element.GetBindingExpression((DependencyProperty)field.GetValue(null));
                    if (be != null && be.ParentBinding != null && be.ParentBinding.Path != null)
                    {
                        // Found a BindingExpression, ensure it has valid data
                        entity = be.DataItem != null ? be.DataItem : element.DataContext;
                        if (entity != null)
                        {
                            if (be.ParentBinding.Mode == BindingMode.TwoWay)
                            {
                                bindingExpression = be;
                                // A twoway binding will be automatically chosen and the rest ignored
                                break;
                            }

                            // Perform an arbitrary sort on path (string), so the same dependency property is chosen consistently.
                            // Reflection ordering is not deterministic and if we just pick the first, we could be
                            // matched with different dependency properties depending on the run.
                            if (bindingExpression == null || string.Compare(be.ParentBinding.Path.Path, bindingExpression.ParentBinding.Path.Path, StringComparison.Ordinal) < 0)
                            {
                                bindingExpression = be;
                            }
                        }
                    }
                }
            }
            if (bindingExpression != null)
            {
                ValidationMetadata newVMD = ParseMetadata(bindingExpression.ParentBinding.Path.Path, entity);
                element.SetValue(ValidationMetadataProperty, newVMD);
                return(newVMD);
            }
            return(null);
        }
예제 #4
0
 /// <summary>
 /// Sets the ValidationMetadata property for the input control
 /// </summary>
 /// <param name="inputControl">The input control to set the ValidationMetadata property on.</param>
 /// <param name="value">The ValidationMetadata to associate with the input control.</param>
 internal static void SetValidationMetadata(DependencyObject inputControl, ValidationMetadata value)
 {
     if (inputControl == null)
     {
         throw new ArgumentNullException("inputControl");
     }
     inputControl.SetValue(ValidationMetadataProperty, value);
 }
예제 #5
0
        public static void AddValidationAttribute <TAttribute>(this ValidationMetadata metadata,
                                                               TAttribute validAttribute) where TAttribute : Attribute

        {
            var attribute = metadata.ValidatorMetadata.OfType <TAttribute>().FirstOrDefault();

            if (attribute != null)
            {
                metadata.ValidatorMetadata.Remove(attribute);
            }
            metadata.ValidatorMetadata.Add(validAttribute);
        }
예제 #6
0
    public ValidationMetadataProviderContext(
        ModelMetadataIdentity key,
        ModelAttributes attributes)
    {
        if (attributes == null)
        {
            throw new ArgumentNullException(nameof(attributes));
        }

        Key                 = key;
        Attributes          = attributes.Attributes;
        ParameterAttributes = attributes.ParameterAttributes;
        PropertyAttributes  = attributes.PropertyAttributes;
        TypeAttributes      = attributes.TypeAttributes;

        ValidationMetadata = new ValidationMetadata();
    }
 public void ValidationMetadata()
 {
     ValidationHelperTestPage page = new ValidationHelperTestPage();
     Assert.IsNull(ValidationHelper.GetValidationMetadata(page.nameContentControl));
     ValidationMetadata vmd = new ValidationMetadata();
     vmd.Caption = "ValidationMetadata";
     ValidationHelper.SetValidationMetadata(page.nameContentControl, vmd);
     Assert.AreEqual(vmd, ValidationHelper.GetValidationMetadata(page.nameContentControl));
     ValidationHelper.SetValidationMetadata(page.nameContentControl, null);
     Assert.IsNull(ValidationHelper.GetValidationMetadata(page.nameContentControl));
     ExceptionHelper.ExpectArgumentNullException(
         delegate { ValidationHelper.GetValidationMetadata(null); }, 
         "inputControl");
     ExceptionHelper.ExpectArgumentNullException(
         delegate { ValidationHelper.SetValidationMetadata(null, vmd); }, 
         "inputControl");
 }
예제 #8
0
        public void ParseMetadata()
        {
            Customer c = new Customer();

            // Normal
            ValidationMetadata vmd = ValidationHelper.ParseMetadata("Name", c);

            Assert.AreEqual("Name", vmd.Caption);
            Assert.AreEqual("This is your first name.", vmd.Description);

            // DisplayAttribute appears first
            // Name is different than property name
            vmd = ValidationHelper.ParseMetadata("BirthDate", c);
            Assert.AreEqual("Birth date", vmd.Caption);
            Assert.AreEqual("This is the day you were born.", vmd.Description);

            // No Name specified
            vmd = ValidationHelper.ParseMetadata("Password", c);
            Assert.AreEqual("Password", vmd.Caption);
            Assert.AreEqual("This is your password", vmd.Description);

            // Empty name specified
            vmd = ValidationHelper.ParseMetadata("EmptyName", c);
            Assert.AreEqual("", vmd.Caption);
            Assert.AreEqual("This is your EmptyName", vmd.Description);

            // No description
            vmd = ValidationHelper.ParseMetadata("SecretAnswer", c);
            Assert.AreEqual("Secret Answer", vmd.Caption);
            Assert.AreEqual(null, vmd.Description);

            // No DisplayAttribute
            vmd = ValidationHelper.ParseMetadata("Warnings", c);
            Assert.AreEqual("Warnings", vmd.Caption);
            Assert.AreEqual(null, vmd.Description);

            // Only ShortName
            vmd = ValidationHelper.ParseMetadata("OnlyShortName", c);
            Assert.AreEqual("OnlyShortName", vmd.Caption);
            Assert.AreEqual(null, vmd.Description);

            // Invalid MemberName
            vmd = ValidationHelper.ParseMetadata("test", c);
            Assert.IsNull(vmd);
        }
예제 #9
0
        public void ValidationMetadata()
        {
            ValidationHelperTestPage page = new ValidationHelperTestPage();

            Assert.IsNull(ValidationHelper.GetValidationMetadata(page.nameContentControl));
            ValidationMetadata vmd = new ValidationMetadata();

            vmd.Caption = "ValidationMetadata";
            ValidationHelper.SetValidationMetadata(page.nameContentControl, vmd);
            Assert.AreEqual(vmd, ValidationHelper.GetValidationMetadata(page.nameContentControl));
            ValidationHelper.SetValidationMetadata(page.nameContentControl, null);
            Assert.IsNull(ValidationHelper.GetValidationMetadata(page.nameContentControl));
            ExceptionHelper.ExpectArgumentNullException(
                delegate { ValidationHelper.GetValidationMetadata(null); },
                "inputControl");
            ExceptionHelper.ExpectArgumentNullException(
                delegate { ValidationHelper.SetValidationMetadata(null, vmd); },
                "inputControl");
        }
예제 #10
0
        /// <summary>
        /// Load meta data and update the UI.
        /// </summary>
        /// <param name="forceUpdate">If true, metadata will not be loaded from cache.</param>
        private void LoadMetadata(bool forceUpdate)
        {
            ValidationMetadata vmd               = null;
            object             entity            = null;
            BindingExpression  bindingExpression = null;

            if (!String.IsNullOrEmpty(this.PropertyPath))
            {
                entity = this.DataContext;
                // Pull metadata directly from the DataContext.  This isn't cached so it will be pulled every time.
                vmd = ValidationHelper.ParseMetadata(this.PropertyPath, entity);
            }
            else if (this.Target != null)
            {
                // Pull the metadata from the target FrameworkElement.
                vmd = ValidationHelper.ParseMetadata(this.Target, forceUpdate, out entity, out bindingExpression);
            }
            if (this.ValidationMetadata != vmd)
            {
                this.ValidationMetadata = vmd;
                // Update to the new VMD
                if (this.ValidationMetadata != null)
                {
                    string newContent = this.ValidationMetadata.Caption;
                    if (newContent != null && this._canContentUseMetaData)
                    {
                        this.SetContentInternally(newContent);
                    }
                }
                else if (this._canContentUseMetaData)
                {
                    // The Target property was reset. Since the Content property
                    // was using the metadata, it also needs to be reset.
                    this.SetContentInternally(null);
                }

                if (!this._isRequiredOverridden)
                {
                    bool isRequired = this.ValidationMetadata == null ? false : this.ValidationMetadata.IsRequired;
                    SetValue(Label.IsRequiredProperty, isRequired);
                }
            }
        }
예제 #11
0
        private void Target_BindingValidationError(object sender, ValidationErrorEventArgs e)
        {
            FrameworkElement inputControl = e.OriginalSource as FrameworkElement;

            if (e != null && e.Error != null && e.Error.ErrorContent != null && inputControl != null)
            {
                string message = e.Error.ErrorContent.ToString();
#if NETSTANDARD
                string key = String.IsNullOrEmpty(inputControl.Name) ? inputControl.GetHashCode().ToString(CultureInfo.InvariantCulture) : inputControl.Name;
#else
                string key = String.IsNullOrEmpty(inputControl.Name) ? inputControl.GetHashCode().ToString(null, CultureInfo.InvariantCulture) : inputControl.Name;
#endif
                key += message;
                if (this._validationSummaryItemDictionary.ContainsKey(key))
                {
                    ValidationSummaryItem existingError = this._validationSummaryItemDictionary[key];
                    this._errors.Remove(existingError);
                    this._validationSummaryItemDictionary.Remove(key);
                }
                if (e.Action == ValidationErrorEventAction.Added)
                {
                    if (GetShowErrorsInSummary(inputControl))
                    {
                        // New error
                        string             propertyName = null;
                        object             entity;
                        BindingExpression  be;
                        ValidationMetadata vmd = ValidationHelper.ParseMetadata(inputControl, false, out entity, out be);
                        if (vmd != null)
                        {
                            propertyName = vmd.Caption;
                        }
                        ValidationSummaryItem vsi = new ValidationSummaryItem(message, propertyName, ValidationSummaryItemType.PropertyError, new ValidationSummaryItemSource(propertyName, inputControl as Control), null);
                        this._errors.Add(vsi);
                        this._validationSummaryItemDictionary[key] = vsi;
                    }
                }
            }
        }
예제 #12
0
        protected override void WriteHtml(HtmlTextWriter writer)
        {
            if (!Columns.Any() && AutoGenerateColumns)
            {
                foreach (GridColumnBase <T> column in new GridColumnGenerator <T>(this).GetColumns())
                {
                    Columns.Add(column);
                }
            }

            var orignalClientValidationEnabled = ViewContext.ClientValidationEnabled;
            var originalFormContext            = ViewContext.FormContext;

            try
            {
                ViewContext.ClientValidationEnabled = true;
                ViewContext.FormContext             = new FormContext
                {
                    FormId = Name + "form"
                };

                if (Editable.Enabled && IsClientBinding)
                {
                    InitializeEditors();
                }

                AdjustColumnsTypesFromDynamic();

                if (!HtmlAttributes.ContainsKey("id"))
                {
                    HtmlAttributes["id"] = Id;
                }

                var builder = htmlBuilderFactory.CreateBuilder(Scrollable.Enabled);

                if (DataSource.Type != DataSourceType.Custom || DataSource.CustomType == "aspnetmvc-ajax")
                {
                    ProcessDataSource();
                }

                if (DataSource.Schema.Model.Id != null)
                {
                    DataKeys.Add(DataSource.Schema.Model.Id);
                }

                var renderingData = CreateRenderingData();

                var functionalData = CreateFunctionalData();

                var container = builder.CreateGrid(HtmlAttributes, functionalData, renderingData);

                if (Editable.Mode == GridEditMode.PopUp && (CurrentItemMode == GridItemMode.Insert || CurrentItemMode == GridItemMode.Edit))
                {
                    AppendPopupEditor(container, renderingData);
                }

                container.WriteTo(writer);

                if (ViewContext.FormContext != null)
                {
                    ValidationMetadata.Add("Fields", ProcessValidationMetadata());

                    ValidationMetadata.Add("FormId", ViewContext.FormContext.FormId);
                }
            }
            finally
            {
                ViewContext.FormContext             = originalFormContext;
                ViewContext.ClientValidationEnabled = orignalClientValidationEnabled;
            }

            base.WriteHtml(writer);
        }
예제 #13
0
 /// <summary>
 /// 验证失败返回值
 /// </summary>
 /// <param name="context"></param>
 /// <param name="metadata"></param>
 /// <returns></returns>
 public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
 {
     return(new JsonResult(RESTfulResult(StatusCodes.Status400BadRequest, errors: metadata.ValidationResult)));
 }
예제 #14
0
        /// <summary>
        /// Parse metadata given a binding path and entity object.
        /// </summary>
        /// <param name="bindingPath">The bindingPath is the name of the property on the entity from which to pull metadata from.  This supports dot notation.</param>
        /// <param name="entity">The entity object from which to pull metadata from.</param>
        /// <returns>The validation metadata associated with the entity and binding path.  This will return null if none exists.</returns>
        internal static ValidationMetadata ParseMetadata(string bindingPath, object entity)
        {
            if (entity != null && !String.IsNullOrEmpty(bindingPath))
            {
                Type         entityType = entity.GetType();
                PropertyInfo prop       = GetProperty(entityType, bindingPath);
                if (prop != null)
                {
                    ValidationMetadata newVMD     = new ValidationMetadata();
                    object[]           attributes = prop.GetCustomAttributes(false);
                    foreach (object propertyAttribute in attributes)
                    {
                        // Loop through each attribute and update the VMD as appropriate

                        // RequiredField
#if NETSTANDARD
                        RequiredAttribute reqAttribute = propertyAttribute as RequiredAttribute;
                        if (reqAttribute != null)
                        {
                            newVMD.IsRequired = true;
                            continue;
                        }
#else // BRIDGE
                        Type attrType = propertyAttribute.GetType();
                        if (attrType.Name == "RequiredAttribute" &&
                            attrType.Namespace == "System.ComponentModel.DataAnnotations")
                        {
                            newVMD.IsRequired = true;
                            continue;
                        }
#endif

                        // Display attribute parsing
#if NETSTANDARD
                        DisplayAttribute displayAttribute = propertyAttribute as DisplayAttribute;
                        if (displayAttribute != null)
                        {
                            newVMD.Description = displayAttribute.GetDescription();
                            newVMD.Caption     = displayAttribute.GetName();
                            continue;
                        }
#else // BRIDGE
                        attrType = propertyAttribute.GetType();
                        if (attrType.Name == "DisplayAttribute" &&
                            attrType.Namespace == "System.ComponentModel.DataAnnotations")
                        {
                            newVMD.Description = (string)attrType.GetMethod("GetDescription",
                                                                            BindingFlags.Public | BindingFlags.Instance)
                                                 .Invoke(propertyAttribute, new object[0]);
                            newVMD.Caption = (string)attrType.GetMethod("GetName",
                                                                        BindingFlags.Public | BindingFlags.Instance)
                                             .Invoke(propertyAttribute, new object[0]);
                            continue;
                        }
#endif
                    }
                    if (newVMD.Caption == null)
                    {
                        // If the name is not defined via the DisplayAttribute, use the property name.
                        newVMD.Caption = prop.Name;

                        // Caption can be set to empty string to have an empty Caption and not default
                        // to the property name.
                    }

                    return(newVMD);
                }
            }
            return(null);
        }
예제 #15
0
        protected override void WriteHtml(HtmlTextWriter writer)
        {
            if (!Columns.Any() && AutoGenerateColumns)
            {
                foreach (GridColumnBase <T> column in new GridColumnGenerator <T>(this).GetColumns())
                {
                    Columns.Add(column);
                }
            }

#if MVC2 || MVC3
            var orignalClientValidationEnabled = ViewContext.ClientValidationEnabled;
            var originalFormContext            = ViewContext.FormContext;

            try
            {
                ViewContext.ClientValidationEnabled = true;
                ViewContext.FormContext             = new FormContext
                {
                    FormId = Name + "form"
                };

                if (Editing.Enabled && IsClientBinding)
                {
                    InitializeEditors();
                }
#endif

#if MVC3
            AdjustColumnsTypesFromDynamic();
#endif
            RegisterScriptFiles();

            if (!HtmlAttributes.ContainsKey("id"))
            {
                HtmlAttributes["id"] = Id;
            }

            var builder = htmlBuilderFactory.CreateBuilder(Scrolling.Enabled);

            var renderingData = CreateRenderingData();

            var functionalData = CreateFunctionalData();

            var container = builder.CreateGrid(HtmlAttributes, functionalData, renderingData);

            if (Editing.Mode == GridEditMode.PopUp && (CurrentItemMode == GridItemMode.Insert || CurrentItemMode == GridItemMode.Edit))
            {
                AppendPopupEditor(container, renderingData);
            }

            container.WriteTo(writer);

#if MVC2 || MVC3
            if (ViewContext.FormContext != null)
            {
                ValidationMetadata.Add("Fields", ProcessValidationMetadata());

                ValidationMetadata.Add("FormId", ViewContext.FormContext.FormId);
            }
        }

        finally
        {
            ViewContext.FormContext             = originalFormContext;
            ViewContext.ClientValidationEnabled = orignalClientValidationEnabled;
        }
#endif
            base.WriteHtml(writer);
        }