8
votes

Itérant sur les propriétés d'une expression lambda

J'essaie de générer un contrôle complexe utilisé dans mon site Web, mais avec différents domaines. La fonctionnalité du contrôle est toujours la même, ce sont les champs sous-jacents qui changent.

Pour obtenir la méthode de montrer différents champs, je tente de créer une extension HTMLHelper qui accepte une expression > code> comme paramètre, qui contiendrait les propriétés d'une classe requise pour afficher le contrôle. Par exemple: p>

la vue: p> xxx pré>

C'est l'extension que je rencontre des problèmes - Comment puis-je itération sur les paramètres fournis dans la Lambda à Fournissez chacun avec un textboxfor () code>, ou même créer manuellement une entrée d'entrée code> et le peupler avec la valeur code> code> et nom code > du paramètre Lambda? p>

L'extension dans PSEDEDO: P>

public static MvcHtmlString MyHelper<TModel,TProperty>(
    this HtmlHelper<TModel> helper, 
    Expression<Func<TModel,TProperty>> expression) {
    foreach (var parameter in expression.???) {
        // helper.TextBoxFor(???) 
        // TagBuilder("input").Attributes("name", expression.???)
    }
}


1 commentaires

Après avoir réaffecté la question et ma réponse, j'ai réalisé que mon premier exemple ne pouvait pas gérer d'accéder à des valeurs de propriétés complexes sur le modèle. J'ai mis à jour mon exemple de code pour tenir compte de cette situation.


4 Réponses :


2
votes

L'expression que vous aurez créé sera relativement compliquée - cela nécessitera de récupérer toutes les propriétés, puis d'appeler le constructeur de type anonyme. "Démontage" qui peut devenir douloureux ... Bien que si vous voulez toujours essayer, je suggérerais de laisser une implémentation de méthode vide et de regarder dans le débogueur pour voir à quoi ressemble l'expression.

Si vous seriez heureux. Pour vous contenter d'une forme légèrement laidienne de code d'appel, il serait beaucoup em> plus simple à implémenter ceci: p> xxx pré>

vous pouvez faire qui prendra un paramètres expression code> ou vous pouvez déclarer plusieurs surcharges avec différents numéros de paramètres, par exemple P>

// Overload for one property
MyHelper<TModel, TProperty1>(this ..., Expression<Func<TModel, TProperty1>> func1)

// Overload for two properties
MyHelper<TModel, TProperty1, TProperty2>(this ...,
   Expression<Func<TModel, TProperty1>> func1,
   Expression<Func<TModel, TProperty2>> func2)


1 commentaires

J'avais envisagé cette approche, mais comme vous le dites que c'est un peu disgracieux, je vais le garder comme un «plan B». :) Merci d'avoir répondu, Jon.



2
votes

Si vous supposez ce qui suit:

  1. Le résultat de l'expression d'entrée est une projection (renvoie un nouvel objet, anonyme ou autre)
  2. Les éléments de la projection sont tous mémorexpressions et ne contiennent pas d'appel à une méthode sur le modèle ou sur ses enfants

    alors vous pouvez réaliser ce que vous voulez en utilisant l'approche suivante:

    EDIT:

    Après avoir réalisé que mon premier exemple pourrait Ne manipulez pas les objets avec des propriétés complexes, j'ai mis à jour le code pour utiliser une méthode d'assistance pour accéder aux valeurs de propriété. Cette méthode traverse la chaîne de propriétés à l'aide de la récursivité pour renvoyer les valeurs appropriées. xxx

    Note: Je n'ai pas implémenté cela directement sous forme de méthode d'extension MVC Dans mon IDE, une légère variation de la syntaxe peut être nécessaire.


0 commentaires

1
votes

Peut-être une API de style constructeur pourrait simplifier les choses: xxx

Notez que cela vous permet d'ajouter des paramètres facultatifs au cas où vous en auriez besoin.

Le code regarderait quelque chose comme ça xxx


0 commentaires

1
votes

Considérez ceci:

Créer un dossier App_code

Mettez le fichier d'aide de rasoir Templates.cshtml.

On dirait ci-dessous: xxx

De cette façon, vous n'avez pas à écrire HTML dans les fichiers C #. C'est très pratique.

auteurs.cshtml ressemble au dessous: xxx

books.cshtml ressemble au dessous: xxx < / Pré>

Plugin toutes les propriétés spéciales à mesure que vous avez besoin par classe de modèle. Si cela devient trop compliqué, examinez l'objet dynamique et expando. Cela dépend de la complexité de vos modèles / formes de vue.


0 commentaires