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

возможно ли 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, по крайней мере, мы могли бы использовать сервер.Передача и поддерживать любое состояние в HttpContext.Коллекция элементов. В MVC единственным вариантом, который я вижу, является вызов метода контроллера, непосредственно передающего требуемые аргументы.

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

Я думаю, куда я иду с этим пытается cludge ASP.NET MVC действует как FrontContoller.

любой идеи?

редактировать

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

4 ответов


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

return RedirectToAction("Controller", "Action")

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

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

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

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

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

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

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

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

вместо ~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 для любого объекта, который будет передан в модель


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

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