Halle
Halle

Reputation: 77

list all property names of controls based on condition in C#

I am trying to parse through all properties of all my controls (for example ascx files) from a certain page (this.Page.Controls) in order to obtain the name of the property that has a property value specified by me, for example - what is the name of the property that has the value "this is my header"? (it may very well be a textbox that contains this value).

The below returns this error:

Cannot get inner content of because the contents are not literal. System.Web.UI.HtmlControls.HtmlContainerControl.get_InnerHtml()

not sure what it means or how to correct it.

 public String searchMethod(List<Control> listOfControls, String searchedValue)
        {
            String result = "";

            foreach (var control in listOfControls)
            {
                PropertyInfo[] properties = control.GetType().GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    if (property.PropertyType == typeof (string)) //added condition on this line *******************************
                    {
                        if (property.GetValue(control, null) != null)
                            if (property.GetValue(control, null).ToString().Contains("searched String"))
                            {
                                result = result + property.Name + "/" + property.GetValue(control, null) + "/";
                            }
                    }

                }
            }
            return result;
        }

I suppose it's stuck on a property that doesn't match the requirements, so why doesn't it simply move on to the next until it finds a good fit? Apparently the property that gets it stuck is a System.String Inner.Html

PS. I've tested the listOfControls fed to the method and it's being generated correctly

Later Update: Another method I am trying is:

public string Method1(List<Control> controlList, string propName)
        {
            string result = "";
            foreach (var control in controlList)
            {
                foreach(var prop in control.GetType().GetProperties())
                {
                    if(prop.PropertyType == typeof(string))
                    {
                        if((prop.GetValue(control,null).GetType()) == typeof(string))
                            if (prop.GetValue(control, null).ToString().Contains(propName))
                        result += prop.Name + "######";
                    }
                }
            }
            return result;
        }

but with this i get Object reference not set to an instance of an object. on line if((prop.GetValue(control,null).GetType()) == typeof(string))

Upvotes: 0

Views: 768

Answers (2)

Scott Hannen
Scott Hannen

Reputation: 29202

You'll get that error if the control has controls inside of it. Do you need to search controls that may be inside of the controls in the list? If so you'd need to use recursion and keep drilling down into the controls (and any controls inside those) and only check InnerHtml on controls that don't contain other controls.

You can also simplify this a little by only checking the value when property.PropertyType == typeof(string). You could also limit your search to just two properties - Text and InnerHtml if that's applicable.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500375

This is the documented behaviour of HtmlContainerControl.InnerHtml - in the "exceptions" section, it's documented that it will throw HttpException if:

There is more than one HTML server control.
- or -
The HTML server control is not a System.Web.UI.LiteralControl or a System.Web.UI.DataBoundLiteralControl.

It sounds like the latter scenario is occurring in your case. The code doesn't "move on" because an exception is being thrown but not caught.

To be honest, I'd suggest being a bit pickier about the types of control that you check, and I'd probably use specific properties instead of just calling ToString().

Upvotes: 1

Related Questions