2009-10-21 10 views
0

Est-il possible de faire quelque chose comme ça dans un contrôleur ASP.NET MVC?Est-il possible de passer des classes entre les contrôleurs dans ASP.NET MVC?

public ActionResult Index(CustomADT adt) 
{ 
    ... 
} 

Et vous passerez dans une classe à partir d'un autre contrôleur lorsque vous cliquez sur un lien. Ou est-ce seulement possible de faire circuler des cordes?

Edit:

Un peu plus d'élaboration. Disons que j'ai la hiérarchie de classe suivante:

public class Area 
{ 
    public string Name { get; set; } 
    public ICollection<Building> Buildings { get; set; } 
} 

public class Building 
{ 
    public string Name { get; set; } 
} 

Alors Area contient une liste de Buildings. Maintenant, j'ai deux contrôleurs, AreasController et BuildingsController. Les deux ont une méthode Index(). Ce que je voudrais faire est quand cette URL est naviguées:

http://localhost/Areas/

Il y répertorient toutes les zones. Puis, quand vous allez à l'adresse suivante:

http://localhost/Areas/1/Buildings/

Il y liste de tous les bâtiments pour la zone avec ID 1. Dans BuildingsController, je reçois l'ID comme un entier, puis l'utiliser pour trouver la bonne zone, comme si:

public ActionResult Index(int areaId) 
{ 
    var area = areaRepository.GetById(areaId); 
    return View(area.Buildings); 
} 

Maintenant, cela semble assez maladroit pour moi. L'ID de zone doit être reçu en tant qu'int, puis je dois à nouveau cliquer sur le référentiel pour obtenir l'objet réel Area. Est-il possible que je peux le faire à la place:

public ActionResult Index(Area area) 
{ 
    return View(area.Buildings); 
} 

Et pas frapper à nouveau le dépôt et re-récupérer un objet qui a déjà été instancié? Je penche pour non à cause du fonctionnement de HTTP (vous ne pouvez pas placer un objet dans l'URL), mais peut-être que quelqu'un a un tour dans leur sac.

+0

Il semble que vous essayez de résoudre un problème qui n'est pas décrit dans votre question. Quel est le contexte de cette question? – spender

+0

Pas beaucoup de fond, vraiment. Dans tous les didacticiels que j'ai vus, ils ne font que passer des chaînes et des ints (qui sont juste des chaînes de caractères) entre contrôleurs, comme lorsque vous cliquez sur un lien. C'est très bien le fonctionnement de HTTP, mais pas tant que ça fonctionne. Puisque les contrôleurs ne sont que des classes, je me demandais s'il y avait un moyen de passer des classes entre les contrôleurs, mais maintenant que j'y pense, je ne pense pas que ce soit possible parce que vous faites une requête HTTP qui appelle un contrôleur. –

+0

"Et de ne plus rejouer le dépôt et de retrouver un objet qui a déjà été instancié" ... Déjà où? Si votre action de contrôleur ne regarde pas cette chose, ce qui serait? (Comme vous pouvez le constater, la nature sans état de HTTP signifie qu'il n'y a vraiment rien en dehors de votre propre code, malgré le comportement de 'ModelBinder'.) –

Répondre

0

J'ai trouvé une réponse possible ici:

http://msdn.microsoft.com/en-us/library/dd394711%28VS.100%29.aspx

En vertu de la section, passage État entre les méthodes d'action. Fondamentalement, vous stockez l'objet dans le dictionnaire TempData, puis le référence comme une chaîne. C'est une solution moche mais parce qu'elle n'est pas fortement typée.

+0

TempData est * fortement * typé. Ce n'est pas * statiquement * typé, cependant. –

+0

Je pensais que TempData est juste un dictionnaire avec une chaîne magique en tant que clé et la valeur est un objet que vous devez ensuite lancer dans le type correct dans la vue. –

+0

Tout est correct, mais cela ne change pas ce que j'ai écrit. Il y a une différence entre un typage fort et un typage statique. Ce que vous avez besoin de lancer vous dit qu'il n'est pas faiblement typé. Il est, cependant, dynamiquement, par opposition à statiquement, typé. –

2

Oui, c'est possible. Plus encore, il est construit directement dans MVC avec ce qu'on appelle "ModelBinders". Les liants de modèle utilisent la réflexion pour faire correspondre les paires clé/valeur de chaîne de requête/forme avec votre objet de classe CustomADT. Ce que vous avez fonctionnera parfaitement, tant que votre formulaire soumet les mêmes noms de propriété.

Votre formulaire ...

<% using (Html.BeginForm()) { %> 

    <%= Html.TextBox("Title", Model.Title) %> 
    <%= Html.TextBox("Description", Model.Description) %> 

<% } %> 

Votre classe ...

public class CustomADT 
{ 
    public String Title {get; set;} 
    public String Description {get; set;} 
} 

Remarquez comment les propriétés de votre classe correspondent à la forme clé/valeurs? ASP.NET MVC l'a intégré qu'il va les cartographier ensemble, avec votre exemple d'index (CustomADT adt) ci-dessus. Si vous avez des exigences particulières pour la liaison, vous pouvez créer votre propre classe IModelBinder personnalisée et l'enregistrer dans votre global.asax pour les mappages personnalisés entre vos paires clé/valeur de formulaire et votre modèle (classe).(bing it)

Aussi, je recommande fortement de lire sur le modèle "ViewModel" avec ASP.NET MVC (bing it). J'ai également blogué sur la façon d'utiliser des méthodes d'action fortement typées, ce qui vous permet de passer des classes de votre vue à un contrôleur (et dans le contrôleur à, avec les extensions au sein de l'assembly Microsoft.Web.Mvc je mentionne).

http://eduncan911.com/archive/tags/Asp.Net+Mvc/default.aspx

Enfin, il n'y a pas de conversion directe d'un modèle à un querystring pour appeler une autre méthode d'action sur un contrôleur. Mais, vous pouvez utiliser le modèle par défaut de liaison pour refléter votre modèle et créez-les pour vous:

return RedirectToAction("Index", "Home", myCustomADT); 

Je pense que devrait fonctionner comme le dernier paramètre est une collection qui sera ajouté comme querystring. Si ce n'est pas le cas (j'ai des doutes), vous devrez passer chaque propriété dans le cadre d'une collection anonyme (, new {Title = myCustomADT.Title, Description = myCustomADT.Description);). Une meilleure question est: pourquoi voudriez-vous? Vous voulez vraiment rediriger et passer des modèles de vue à la place.

+1

Il peut aussi avoir besoin de redéfinir sa signature de contrôleur en tant qu'indice public ActionResult ([Bind (Prefix = "")] CustomADT adt) '. – Jason

+0

J'ai révisé ma question avec une meilleure clarification de ce que j'essaie de faire. Je pense que ce que je veux faire est un peu différent de ce que vous avez décrit. –

Questions connexes