2009-09-30 6 views
7

Est-il possible pour un automate ASP.NET MVC de créer une nouvelle instance d'un contrôleur différent et de déléguer efficacement la responsabilité à cet égard?Contrôleur d'instanciation .NET MVC à l'intérieur d'un autre contrôleur

Disons par exemple que j'ai deux contrôleurs dans le répertoire/contrôleurs/répertoire:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
      var otherController = new OtherController(); 
      return otherController.ShowNumberOfThings(100); 
    } 
} 

public class OtherController : Controller 
{ 
     public ActionResult ShowNumberOfThings(int index) 
     { 
      return View(index); 
     } 
} 

... et une vue appelée Vues/Autre/ShowNumberOfThings.aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage<int>" %> 
Number of things: <%= Model.ToString() %> 

Lorsque je frappe l'url:

http://localhost/Home/Index

Je veux être présent ed avec une page qui se lit comme suit:

« Nombre de choses: 100 »

Je voudrais être en mesure de maintenir les données temporaires entre redirections du contrôleur sans être forcé d'utiliser l'objet de la session (TempData [ « »] utilisations l'objet de session pour les redirections de contrôleur croisé). Mon cas réel a un objet complexe qui doit passer (pas seulement un int), donc l'utilisation d'un URL/Cookie est hors de question, et l'état de la session est un non-non. Dans WebForms, nous pourrions au moins utiliser Server.Transfer et conserver n'importe quel état dans la collection HttpContext.Items. Dans MVC, la seule option que je peux voir est d'appeler la méthode du contrôleur en passant directement dans les arguments requis.

À l'heure actuelle, il a du mal à essayer de résoudre le dossier de vue car le "contexte" est toujours en cours d'exécution sous le HomeController.

Je devine où je vais avec ceci essaye d'inciter ASP.NET MVC à agir comme un FrontContoller.

Des idées?

EDIT

En fin de compte nous avons dû serialise tout en une session et utiliser. Dommage, mais j'ai entendu dire que MVC2 supportera la sérialisation des objets dans un ViewState.

+0

J'ai fait quelque chose de très similaire à cela qui a bien fonctionné - le modèle devrait être passé correctement, alors qu'est-ce que c'est que le contexte pose problème? – Keith

Répondre

2

Je pense qu'il serait préférable d'utiliser.

return RedirectToAction("Controller", "Action") 

Cependant, je suppose que vous voulez maintenir l'index/index de l'url. Si vous examinez le modèle FrontController, vous devez étudier l'écriture d'un Custom ControllerFactory qui hérite de DefaultControllerFactory, puis remplacer la méthode CreateController. Vous pouvez enregistrer votre usine en utilisant le code ci-dessous.

protected void Application_Start() 
    { 
     ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactory(); 
     RegisterRoutes(RouteTable.Routes); 
    } 

Dans l'usine de contrôleur vous avez accès à l'RequestContext afin que vous puissiez changer le RouteData au besoin et déléguer au contrôleur correct.

Vous pouvez bien sûr définir un itinéraire personnalisé pour Home/Index qui va à OtherController.ShowNumberOfThings()

routes.MapRoute("Home", "Home/Index/{id}", 
          new {controller = "Other", action = "ShowNumberOfThings", id = 100}); 
+1

Je ne peux pas utiliser RedirectToAction car cela entraîne deux requêtes HTTP. Dans ma situation, je dois passer un objet complexe, pas un int, donc je ne peux pas vraiment le sérialiser en un paramètre querystring (route). Bonne réponse si. – Codebrain

3

Si vous voulez être présenté avec « Nombre de choses: 100 » lorsque vous appuyez sur l'action Index pourquoi rendent pas directement la vue correspondante:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View("~Views/Other/ShowNumberOfThings.aspx", 100); 
    } 
} 
1

une approche différente serait l'utilisation des vues partielles

au lieu de ~Views/Other/ShowNumberOfThings.aspx

vous pouvez mettre votre vue en ~Views/shared/ShowNumberOfThings.ascx

ont à la fois des vues ~Views/Other/ShowNumberOfThings.aspx et ~Views/Home/Index.aspx mettre en œuvre la vue partielle

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
      return View(100); 
    } 
} 

public class OtherController : Controller 
{ 
     public ActionResult ShowNumberOfThings(int index) 
     { 
      return View(index); 
     } 
} 

et dans les deux vues mettre en œuvre la vue partielle

<% Html.RenderPartial("~Views/shared/ShowNumberOfThings.ascx", ViewData.Model); %> 

vous pouvez modifier l'int pour tout objet qui sera transmis à la modèle

0

Une autre possibilité (semblable aux vues partielles) est d'utiliser Html.RenderAction. Cela permet différentes classes de modèle de vue et des méthodes de contrôleur distinctes.

<% Html.RenderAction("yourActionName", "yourControllerName", routeValues); %> 
Questions connexes