Iterieren über Eigenschaften eines Lambda-Ausdrucks

8

Ich versuche, ein komplexes Steuerelement, das auf meiner Website häufig, aber mit verschiedenen Feldern verwendet wird, zu generalisieren. Die Funktionalität in der Steuerung ist immer die gleiche, es sind nur die zugrunde liegenden Felder, die sich ändern.

Um die Methode zum Anzeigen verschiedener Felder zu erreichen, versuche ich eine HTMLHelper-Erweiterung zu erstellen, die einen Expression<Func<TModel,TProperty>> als Parameter akzeptiert, der die Eigenschaften einer Klasse enthält, die für die Anzeige im Steuerelement benötigt wird. Zum Beispiel:

Die Ansicht:

%Vor%

Es ist die Erweiterung, mit der ich Probleme habe - wie kann ich über die bereitgestellten Parameter im Lambda iterieren, um jeweils TextBoxFor() bereitzustellen, oder manuell ein input -Element erstellen und es mit value füllen und name des Lambda-Parameters?

Die Erweiterung in psuedo:

%Vor%

Ich habe das Gefühl, dass ich das viel zu lange angeguckt habe, und ich habe auch das Gefühl, dass ich es auf eine einfachere Weise übersehe, dies zu erreichen.

Jede Hilfe wird sehr geschätzt. Wenn Sie weitere Informationen benötigen oder etwas Wichtiges verpasst haben, lassen Sie es mich wissen.

    
Rory McCrossan 10.09.2012, 19:14
quelle

4 Antworten

2

Wenn Sie Folgendes annehmen:

  1. Das Ergebnis des Eingabeausdrucks ist eine Projektion (gibt ein neues Objekt zurück, anonym oder anders)
  2. Die Elemente der Projektion sind alle MemberExpressions und enthalten keinen Aufruf einer Methode auf dem Modell oder auf seinen untergeordneten Elementen

Dann können Sie erreichen, was Sie wollen, indem Sie den folgenden Ansatz verwenden:

Bearbeiten:

Nachdem ich festgestellt habe, dass mein erstes Beispiel keine Objekte mit komplexen Eigenschaften verarbeiten konnte, habe ich den Code aktualisiert, um eine Hilfsmethode für den Zugriff auf Eigenschaftswerte zu verwenden. Diese Methode verwendet die Rekursion, um die entsprechenden Werte zurückzugeben.

%Vor%

Hinweis: Ich habe dies nicht direkt als eine MVC-Erweiterungsmethode in meiner IDE implementiert, daher kann eine leichte Variation der Syntax erforderlich sein.

    
mclark1129 10.09.2012, 19:52
quelle
2

Der von Ihnen erstellte Ausdruck ist relativ kompliziert - Sie müssen alle Eigenschaften abrufen und dann den anonymen Typkonstruktor aufrufen. "Disassembling", das kann schmerzhaft werden ... obwohl, wenn Sie immer noch versuchen wollen, würde ich vorschlagen, nur eine leere Methodenimplementierung zu lassen und im Debugger nachzusehen, wie der Ausdruck aussieht.

Wenn Sie sich mit einer etwas hässlicheren Form von aufrufendem Code begnügen würden, wäre es viel einfacher, dies zu implementieren:

%Vor%

Sie könnten dafür einen params Expression<TModel, object> verwenden, oder Sie könnten mehrere Überladungen mit einer anderen Anzahl von Parametern deklarieren, z. B.

%Vor%

usw.

    
Jon Skeet 10.09.2012 19:23
quelle
1

Vielleicht könnte eine API im Builder-Stil die Dinge vereinfachen:

%Vor%

Beachten Sie, dass Sie damit optionale Parameter hinzufügen können, falls Sie sie benötigen.

Der Code würde ungefähr so ​​aussehen

%Vor%     
default.kramer 10.09.2012 19:59
quelle
1

Bedenken Sie Folgendes:

App_Code-Ordner erstellen

Setzen Sie die Rasierer-Hilfsdatei Templates.cshtml.

Es sieht wie folgt aus:

%Vor%

Auf diese Weise müssen Sie nicht HTML in C # Dateien schreiben. Es ist sehr praktisch.

Authors.cshtml sieht wie folgt aus:

%Vor%

books.cshtml sieht wie folgt aus:

%Vor%

Fügen Sie alle speziellen Eigenschaften hinzu, die Sie für jede Modellklasse benötigen. Wenn es zu kompliziert wird, sehen Sie sich das dynamische und expando-Objekt an. Es hängt davon ab, wie komplex Ihre Modelle / Viewmodels sind.

    
Yogiraj 10.09.2012 22:58
quelle

Tags und Links