2009-09-30 17 views
7

Czy jest możliwe, aby kontroler ASP.NET MVC tworzył nowe wystąpienie innego kontrolera i skutecznie delegował na to rezonans?.NET Kontroler instancji MVC wewnątrz innego kontrolera

Załóżmy na przykład, że mam dwa kontrolery w/controllers/katalogu:

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); 
     } 
} 

... i widok nazywany views/Inne/ShowNumberOfThings.aspx:

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

Kiedy I hit URL:

http://localhost/Home/Index

Chcę być obecny ed ze strony, która brzmi:

„wiele rzeczy: 100”

Chciałbym, aby móc utrzymywać tymczasowe dane między przekierowań kontrolera bez zmuszony do korzystania z obiektu sesji (TempData [ „”] Zastosowania obiekt sesji dla przekierowań między kontrolerami). Moja prawdziwa światowa sprawa ma złożony obiekt, który wymaga przekazania (nie tylko int), więc używanie adresu URL/ciasteczka nie wchodzi w grę, a stan sesji jest nie-nie.

Przynajmniej w WebForms moglibyśmy używać Server.Transfer i utrzymywać dowolny stan w kolekcji HttpContext.Items. W MVC jedyną opcją jaką widzę jest wywołanie metody kontrolera bezpośrednio przekazującej wymagane argumenty.

W tej chwili występują problemy z próbą rozwiązania folderu widoku, ponieważ "kontekst" nadal działa w HomeController.

Zgaduję, gdzie idę z tym próbuje osaczyć ASP.NET MVC działając jak FrontContoller.

Wszelkie pomysły?

EDIT

W końcu musieliśmy serialise wszystko do sesji i użyć jej. Szkoda, ale słyszałem, że MVC2 będzie obsługiwać obiekty szeregujące w ViewState.

+0

Zrobiłem coś bardzo podobnego do tego, co działało bez zarzutu - model powinien być poprawnie przekazany, więc co to jest w kontekście, który stanowi problem? – Keith

Odpowiedz

2

Myślę, że byłoby lepiej używać.

return RedirectToAction("Controller", "Action") 

Zgaduję jednak, że chcesz zachować adres URL/indeks URL. Jeśli patrzysz na wzorzec FrontController, powinieneś zbadać napisanie Custom ControllerFactory, który dziedziczy po DefaultControllerFactory, a następnie Zastąpić metodę CreateController. Możesz zarejestrować swoją fabrykę, korzystając z poniższego kodu.

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

W fabryce Controller masz dostęp do RequestContext więc można zmienić RouteData jako potrzebne i przekazać do odpowiedniego sterownika.

Można oczywiście ustawić niestandardową trasę dla Home/Index, która przechodzi do OtherController.ShowNumberOfThings()

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

Nie mogę użyć funkcji RedirectToAction, ponieważ powoduje to dwa żądania HTTP. W mojej sytuacji muszę przekazać obiekt złożony, a nie int, więc nie mogę serializować go w parametrze querystring (route). Dobra odpowiedź. – Codebrain

3

Jeśli chcesz być prezentowane z „wiele rzeczy: 100” po trafieniu akcji index dlaczego nie bezpośrednio renderować odpowiedni widok:

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

inne podejście byłoby korzystanie z częściowym widokiem

zamiast ~Views/Other/ShowNumberOfThings.aspx

można umieścić swój pogląd w ~Views/shared/ShowNumberOfThings.ascx

mieć oba poglądy ~Views/Other/ShowNumberOfThings.aspx i ~Views/Home/Index.aspx wdrożyć częściowy widok

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

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

iw obu poglądów wdrożenia częściowy widok

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

można zmienić int dla dowolnego obiektu, który zostanie przekazany do model

0

Inną możliwością (podobną do widoków częściowych) jest użycie Html.RenderAction. Pozwala to na różne klasy modeli widoków i oddzielne metody kontrolerów.

<% Html.RenderAction("yourActionName", "yourControllerName", routeValues); %> 
Powiązane problemy