2010-12-14 23 views
0

Nous avons un modèle (par exemple, List<string>). La fonction qui construit la liste est non déterministe et la sortie est nécessaire pour être référencée à la fois dans le contrôleur et dans la vue pendant la durée de vie de la requête. Comme c'est par requête, il ne peut pas être statique ou singleton.Comment gérer les données partagées entre le contrôleur et la vue dans ASP.NET MVC?

Il s'agit d'une structure commune qui peut être référencée à partir de n'importe quelle vue ou contrôleur.

Puisque nous ne pouvons pas accéder au contrôleur à partir de la vue (par principe, et nous sommes d'accord), nous ne pouvons pas le garder dans le contrôleur. Nous le conservons actuellement dans le dictionnaire ViewData et l'initialisons dans le contrôleur ou dans la vue (si le contrôleur n'en a pas besoin).

Nous pensons qu'utiliser ViewData à cet effet n'est peut-être pas idéal car il n'est pas créé pour être consommé par un contrôleur en premier lieu. Existe-t-il un meilleur moyen de partager des données communes par requête entre le contrôleur et la vue? Sinon, nous resterons avec ViewData.

Il y a HttpContext.Items dictionnaire mais je ne suis pas sûr que cela corresponde à ce but.

+1

"Il existe un dictionnaire HttpContext.Items mais je ne suis pas sûr que cela corresponde à ce but." - ça rentre. Utiliser ça. –

+0

"initialisez-le dans une vue ou un contrôleur, selon celui qui s'exécute en premier." - Comment une vue peut-elle fonctionner avant le contrôleur? –

+2

effectivement AFAIK ViewData * est * HttpContext.Current.Items sous le capot. Et depuis quand "ViewData est-il créé pour être consommé par un contrôleur"? Il est consommé par le * View *, où les données sont * fournies * par le contrôleur. – RPM1984

Répondre

1

la sortie est nécessaire pour être référencé dans le contrôleur et la vue pendant toute la durée de la demande

La façon dont fonctionne MVC, le code d'action dans le contrôleur est exécuté, et les données résultant est transmis au moteur de vue qui dessine la page en utilisant les informations que vous avez transmises avec l'appel de View (données) ou dans le dictionnaire ViewData.

Je ne sais pas ce que vous essayez de faire, mais il semble que ce soit plus un problème de mauvaise approche que de technique (j'ai peut-être tort, cependant).

Pourriez-vous expliquer pourquoi vous avez besoin du contrôleur pendant le rendu de la vue? Si vous avez besoin d'une logique associée à la liste (pour la traiter ou faire quoi que ce soit), je créerais simplement une nouvelle classe qui étendrait la liste <T>, ajouterait la logique à cette classe au lieu du contrôleur, et passerait un objet de cette class à la vue, soit en utilisant View() ou ViewData [].

+0

Simple, j'ai besoin des mêmes données pour les décisions de rendu et le contrôleur logique, comme 'OnActionExecuting'. Mais je ne peux pas le récupérer deux fois du service car il modifie les données. –

+1

Mmmm ... Je pense que je commence à comprendre ce que vous essayez de faire. Si je l'avais correctement, j'étendrais la classe du contrôleur avec une nouvelle qui contenait la propriété que vous voulez partager dans les actions, les événements et les attributs du contrôleur, et envoyiez cette propriété à la vue en utilisant ViewData []. – salgiza

+0

Oui, ça a aussi du sens pour moi. Cependant, il y a de fortes chances que le contrôleur n'ait pas du tout besoin de ces données. Et si le contrôleur et la vue ne le référencent pas, nous ne devrions pas appeler le service (alias initialisation paresseuse). C'est pourquoi nous n'initialisons pas toujours le contrôleur. –

0

L'action du contrôleur doit toujours être appelée en premier. Si vous avez plusieurs contrôleurs appelant la même vue/vue partielle alors vous devriez refactoriser le code à une méthode et l'appeler. ViewData est la solution pour cela, si vous voulez vraiment des informations de type "une fois accès" alors peut-être TempData mais ViewData est conçu pour cela.

+0

J'ai édité ma réponse pour clarifier que le contrôleur ne s'est pas exécuté après la vue. C'est juste que le contrôleur peut ne pas accéder aux données du tout et que c'est la responsabilité de la vue de le construire. –

+0

Pas ma réponse, ma question :) –

0

Quelle est la chose exacte que vous essayez de faire?

On dirait que vous venez de poser des questions sur la façon de transmettre certaines données du contrôleur à la vue, ce qui est plutôt une tâche triviale. Utilisez simplement ViewData, yes, ou ViewBag dans le cas MVC3 ou utilisez ViewModels.

Ou y at-il un cas particulier? Que signifie "référencement de Controller et de View"? D'où proviennent les données? Généralement, le contrôleur prépare les données pour la vue et les transmet en tant que ActionResult (ou mieux, en tant que ViewModel). La vue ne devrait jamais prendre elle-même des données en contournant le contrôleur.

+0

Vasilio merci pour votre intérêt, mais cela correspond mieux à un commentaire, pas une réponse :) J'ai une classe de service qui fournit un élément de données. Ces données prennent du temps à produire et il n'est pas possible de les produire deux fois. Par conséquent, je dois le tirer une seule fois. Cependant, les données peuvent être utilisées à la fois dans un contrôleur et dans la vue. Je le construis déjà "à la demande", alors j'essaie de savoir où le placer. –

+0

Eh bien, comme vous pouvez le voir, je commence juste à utiliser ce site. Et malheureusement, il ne me laisse pas ajouter de commentaires, seules les réponses sont permises. Je ne sais pas pourquoi ils ont fait de cette façon, mais son entreprise SO donc je ne prétends pas :) –

+0

Quant à la question: Pourquoi le contrôleur devrait jamais savoir quelque chose initié par View? Le contrôleur prépare généralement toutes les données pour la vue, quel que soit le lieu d'origine des données (Repos, Services, etc.). Si votre Controller a besoin de données provenant de View dans une seule requête, c'est peut-être la raison pour revoir votre architecture. Quoi qu'il en soit, des détails plus précis sur les tâches seraient utiles pour fournir une réponse correcte. –