using System.BusinessObjects.Helpers; using System.Collections; using System.ComponentModel; using System.Web.UI; using System.Web.UI.WebControls; namespace System.BusinessObjects.Validation { [NonVisualControl] public class WebValidationControlExtender : WebControl { private string _attachTo; /// /// Specifies the ObjectDataSource to attach to /// public string AttachTo { get { return _attachTo; } set { _attachTo = value; } } private string _propertyToValidate; /// /// Optionally. Specifies only one property to validate /// public string PropertyToValidate { get { return _propertyToValidate; } set { _propertyToValidate = value; } } private Control attachToControl = null; protected override void Render(HtmlTextWriter writer) { if (DesignMode) { writer.WriteLine(string.Format("[WebValidationControl for {0}]", AttachTo)); } else { base.Render(writer); } } /// /// Accessing controls such as LoginView on the OnInit event causes them not to /// render correctly. This is why the events are now hooked up during onload. /// protected override void OnLoad(EventArgs e) { base.OnLoad(e); attachToControl = WebHelper.FindNestedWebControl(Page.Controls, AttachTo); if(attachToControl != null) //hook up events { if (attachToControl.GetType() == typeof(ObjectDataSource)) { ((ObjectDataSource)attachToControl).Inserting += WebValidationControlExtender_Inserting; ((ObjectDataSource)attachToControl).Updating += WebValidationControlExtender_Updating; } else { throw new ApplicationException(string.Format("WebValidationControlExtender is not compatable with {0} controls", attachToControl.GetType())); } } } void WebValidationControlExtender_Updating(object sender, ObjectDataSourceMethodEventArgs e) { if(!ValidateObjectCollection(e.InputParameters.Values)) e.Cancel = true; } void WebValidationControlExtender_Inserting(object sender, ObjectDataSourceMethodEventArgs e) { if (!ValidateObjectCollection(e.InputParameters.Values)) e.Cancel = true; } protected bool ValidateObjectCollection(ICollection collection) { bool success = true; foreach (object obj in collection) { if (typeof(IDataErrorInfo).IsAssignableFrom(obj.GetType())) { if (!string.IsNullOrEmpty(PropertyToValidate)) { string errorMessage = ((IDataErrorInfo)obj)[PropertyToValidate]; if (!string.IsNullOrEmpty(errorMessage)) { AddErrorControl(errorMessage, PropertyToValidate); success = false; } } else { foreach(PropertyDescriptor info in TypeDescriptor.GetProperties(obj)) { string errorMessage = ((IDataErrorInfo)obj)[info.Name]; if (!string.IsNullOrEmpty(errorMessage)) { AddErrorControl(errorMessage, info.Name); success = false; } } } } } return success; } protected void AddErrorControl(string message, string propertyName) { CustomValidator validator = new CustomValidator(); validator.ErrorMessage = message; validator.IsValid = false; Page.Validators.Add(validator); foreach (DetailsView dv in WebHelper.FindNestedWebControls(Page.Controls, typeof(DetailsView))) { if (dv.DataSourceID == attachToControl.ID) { foreach (DataControlFieldCell cell in WebHelper.FindNestedWebControls(dv.Controls, typeof(DataControlFieldCell))) { if (cell.ContainingField is BoundField && ((BoundField)cell.ContainingField).DataField == propertyName && cell.Controls.Count > 0) { Literal errorMsg = new Literal(); errorMsg.Text = string.Format("*", message); cell.Controls.Add(errorMsg); } } } } } } }