2016-04-25 9 views
0

Ich versuche, alle Eigenschaften aller meiner Steuerelemente (zum Beispiel ascx-Dateien) von einer bestimmten Seite (this.Page.Controls) zu analysieren, um den Namen von zu erhalten die Eigenschaft, die einen von mir angegebenen Eigenschaftswert hat - wie lautet der Name der Eigenschaft, die den Wert "this is my header" hat? (Es kann sehr gut eine Textbox sein, die diesen Wert enthält).Liste aller Eigenschaftsnamen von Steuerelementen basierend auf Bedingung in C#

Die unten gibt diesen Fehler zurück:

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

nicht sicher, was es bedeutet, oder wie es zu korrigieren.

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; 
     } 

Ich nehme an, es auf einem Grundstück festsitzt, die die Anforderungen nicht entsprechen, also warum es nicht einfach zum nächsten weiterziehen, bis es eine gute Passform findet? Anscheinend ist die Eigenschaft, die es stecken bleibt, ein System.String Inner.Html

PS. Ich habe die listOfControls dem Verfahren zugeführt getestet und es ist richtig

Später Aktualisieren erzeugt wird: Eine andere Methode, die ich versucht bin, ist:

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; 
     } 

aber mit diesem i Objektverweis nicht auf eine Instanz von bekommen ein Objekt. on line if((prop.GetValue(control,null).GetType()) == typeof(string))

Antwort

1

Dies ist das dokumentierte Verhalten von HtmlContainerControl.InnerHtml - in den „Ausnahmen“ Abschnitt, es dokumentiert, dass es werfen HttpException wenn:

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.

Es klingt wie das letztere Szenario in Ihrem Fall auftritt. Der Code "geht nicht weiter", weil eine Ausnahme ausgelöst, aber nicht abgefangen wird.

Um ehrlich zu sein, würde ich vorschlagen, ein bisschen wählerischer über die Arten der Kontrolle, die Sie überprüfen, und ich würde wahrscheinlich bestimmte Eigenschaften anstelle nur ToString() aufrufen.

+0

Danke Jon Skeet! Ich habe versucht, Ihren Ratschlag anzuwenden, und habe mir zwei Versionen ausgedacht, mit denen ich meine erste Frage beantwortet habe. Irgendwelche Gedanken? Die zweite Version scheint viel einfacher und sauberer zu sein, wirft aber einen Fehler auf ... schließlich. Ich bin nicht geschickt mit der Syntax. – Halle

+0

@Halle: Nun, das wird fehlschlagen, wenn die Eigenschaft null zurückgibt. Aber es ist unnötig - wenn der Eigenschaftstyp "string" ist, kann er nichts anderes als "string" oder eine Nullreferenz zurückgeben. Noch wichtiger ist, dass Sie immer noch nach dem Wert der gleichen Eigenschaft fragen, die das ursprüngliche Problem verursacht hat. –

+0

@Halle: Wenn die Eigenschaft null zurückgibt, rufen Sie 'GetType()' auf einer Nullreferenz auf - bang. Die Eigenschaft, die das Problem verursacht hat ('HtmlContainer.InnerHtml'), ist nicht" verschiedener Typen "- sie hat den Typ string. Im Grunde genommen vermeidet Ihre Änderung das ursprüngliche Problem nicht, soweit ich sehen kann. –

0

Sie erhalten diesen Fehler, wenn das Steuerelement über Steuerelemente verfügt. Müssen Sie nach Steuerelementen suchen, die sich in den Steuerelementen in der Liste befinden? Wenn dies der Fall ist, müssen Sie die Rekursion verwenden und in den Steuerelementen (und allen darin enthaltenen Steuerelementen) weiter nach unten gehen und nur die Steuerelemente InnerHtml auf Steuerelementen überprüfen, die keine anderen Steuerelemente enthalten.

Sie können dies auch ein wenig vereinfachen, indem Sie nur den Wert property.PropertyType == typeof(string) überprüfen. Sie können Ihre Suche auch auf nur zwei Eigenschaften beschränken - und InnerHtml, falls zutreffend.

+0

Vielen Dank Scott! Ich habe diese Bedingung hinzugefügt, aber bekomme ein "Kann nicht inneren Inhalt bekommen, weil der Inhalt nicht literal ist". Irgendwelche Gedanken, wie man das verbessern kann? 'if (property.PropertyType == typeof (string))' - Sie können es in der bearbeiteten Frage sehen – Halle

Verwandte Themen