Контроллер экземпляра .NET MVC внутри другого контроллера

115
13

Возможно ли, чтобы ASP.NET MVC-контроллер создавал новый экземпляр другого контроллера и эффективно делегировал ему пересохранение?


Скажем, например, что у меня есть два контроллера в каталоге /Controllers/:


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


... и вид под названием Views/Other/ShowNumberOfThings.aspx:


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

Когда я нажимаю на URL:


http://localhost/Home/Index


Я хочу представить страницу, которая гласит:


"Количество вещей: 100"


Я хотел бы иметь возможность сохранять временные данные между перенаправлением контроллера, не будучи вынужденным использовать объект сеанса (TempData [""] использует объект сеанса для перенаправления перекрестных контроллеров). У моего реального мира есть сложный объект, который нуждается в передаче (а не только в int), поэтому использование URL/Cookie не может быть и речи, а состояние сеанса - нет.


В WebForms по крайней мере мы могли бы использовать Server.Transfer и поддерживать любое состояние в коллекции HttpContext.Items. В MVC единственный вариант, который я вижу, - это вызов метода контроллера, который напрямую передается в требуемых аргументах.


В настоящий момент у него возникают проблемы с попыткой разрешить папку вида, поскольку "контекст" все еще работает под HomeController.


Я предполагаю, что я собираюсь с этим пытаться привязать ASP.NET MVC к действию как FrontContoller.


Любые идеи?


ИЗМЕНИТЬ


В конце концов нам пришлось сериализовать все на сеанс и использовать его. Позор, но я слышал, что MVC2 будет поддерживать сериализацию объектов в ViewState.

спросил(а) 2009-09-30T16:57:00+04:00 11 лет назад
1
Решение
70

Я думаю, что было бы предпочтительно использовать.


return RedirectToAction("Controller", "Action")

Однако я предполагаю, что вы хотите сохранить Url Home/Index.
Если вы посмотрите на шаблон FrontController, тогда вам следует исследовать запись пользовательского ControllerFactory, который наследует DefaultControllerFactory, а затем переопределяет метод CreateController.
Вы можете зарегистрировать свой factory, используя следующий код.


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

В контроллере factory у вас есть доступ к RequestContext, поэтому вы можете изменить RouteData по мере необходимости и делегировать правильному контроллеру.


Конечно, вы могли бы просто задать настраиваемый маршрут для Home/Index, который идет в OtherController.ShowNumberOfThings()


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

ответил(а) 2009-10-01T00:38:00+04:00 11 лет назад
81

Если вы хотите, чтобы у вас появилось "Количество вещей: 100", когда вы нажмете на действие "Индекс", почему бы прямо не отобразить соответствующее представление:

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

ответил(а) 2009-10-08T14:42:00+04:00 11 лет назад
58

другим подходом было бы использование частичных представлений


вместо ~Views/Other/ShowNumberOfThings.aspx


вы можете поместить свое представление в ~Views/shared/ShowNumberOfThings.ascx


имеют оба представления ~Views/Other/ShowNumberOfThings.aspx и ~Views/Home/Index.aspx реализуют частичный вид


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

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


и в обоих представлениях реализуется частичный вид


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

вы можете изменить int для любого объекта, который будет передан модели

ответил(а) 2009-11-09T17:35:00+03:00 10 лет, 11 месяцев назад
41

Другая возможность (аналогичная частичным представлениям) заключается в использовании Html.RenderAction. Это позволяет использовать различные классы модели представления и отдельные методы контроллера.


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

ответил(а) 2012-09-11T00:11:00+04:00 8 лет, 1 месяц назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема