/// <summary> /// Routine that can be used read Form Variables into an object if the /// object name and form variable names match either exactly or with a specific /// prefix. /// /// The method loops through all *public* members of the object and tries to /// find a matching form variable by the same name in Request.Form. /// /// The routine returns false if any value failed to parse (ie. invalid /// formatting etc.). However parsing is not aborted on errors so all /// other convertable values are set on the object. /// /// You can pass in a Dictionary<string,string> for the Errors parameter /// to optionally retrieve unbinding errors. The dictionary key holds the /// simple form varname for the field (ie. txtName), the value the actual /// exception error message /// </summary> /// <remarks> /// This method can have unexpected side-effects if multiple naming /// containers share common variable names. This routine is not recommended /// for those types of pages. /// </remarks> /// <param name="Target"></param> /// <param name="FormVarPrefix">empty or one or more prefixes spearated by |</param> /// <param name="errors">Allows passing in a string dictionary that receives error messages. returns key as field name, value as error message</param> /// <returns>true or false if an unbinding error occurs</returns> public static bool FormVarsToObject(object target, string formvarPrefixes = null, Dictionary <string, string> errors = null) { bool isError = false; List <string> ErrorList = new List <string>(); if (formvarPrefixes == null) { formvarPrefixes = ""; } if (HttpContext.Current == null) { throw new InvalidOperationException("FormVarsToObject can only be called from a Web Request"); } HttpRequest Request = HttpContext.Current.Request; // try to get a generic reference to a page for recursive find control // This value will be null if not dealing with a page (ie. in JSON Web Service) Page page = HttpContext.Current.CurrentHandler as Page; MemberInfo[] miT = target.GetType().FindMembers( MemberTypes.Field | MemberTypes.Property, BindingFlags.Public | BindingFlags.Instance, null, null); // Look through all prefixes separated by | string[] prefixes = formvarPrefixes.Split('|'); foreach (string prefix in prefixes) { // Loop through all members of the Object foreach (MemberInfo Field in miT) { string Name = Field.Name; FieldInfo fi = null; PropertyInfo pi = null; Type FieldType = null; if (Field.MemberType == MemberTypes.Field) { fi = (FieldInfo)Field; FieldType = fi.FieldType; } else { pi = (PropertyInfo)Field; FieldType = pi.PropertyType; } // Lookup key will be field plus the prefix string formvarKey = prefix + Name; // Try a simple lookup at the root first var strValue = Request.Form[formvarKey]; // if not found try to find the control and then // use its UniqueID for lookup instead if (strValue == null && page != null) { Control ctl = WebUtils.FindControlRecursive(page, formvarKey); if (ctl != null) { strValue = Request.Form[ctl.UniqueID]; } } // Bool values and checkboxes might require special handling if (strValue == null) { // Must handle checkboxes/radios if (FieldType == typeof(bool)) { strValue = "false"; } // other values that are null are not updated else { continue; } } try { // Convert the value to it target type object Value = ReflectionUtils.StringToTypedValue(strValue, FieldType); // Assign it to the object property/field if (Field.MemberType == MemberTypes.Field) { fi.SetValue(target, Value); } else { pi.SetValue(target, Value, null); } } catch (Exception ex) { isError = true; if (errors != null) { errors.Add(Field.Name, ex.Message); } } } } return(!isError); }