/// <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); } }
/// <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); }
/// <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); }
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); }
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"); }
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); }
/// <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); } } }
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; } } } }
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); }
/// <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))); }
/// <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); }
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); }