.NET MVC在另一个控制器中实例化控制器

时间:2009-09-30 13:57:52

标签: asp.net-mvc controller

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() %>

当我点击网址时:

http://localhost/Home/Index

我希望看到一个页面:

“事情数量:100”

我希望能够在控制器重定向之间保留临时数据而不必强制使用会话对象(TempData [“”]使用会话对象进行跨控制器重定向)。我的真实案例有一个复杂的对象需要传递(不仅仅是一个int),所以使用URL / Cookie是不可能的,会话状态是禁止的。

在WebForms中,我们至少可以使用Server.Transfer并维护HttpContext.Items集合中的任何状态。在MVC中,我能看到的唯一选择是调用控制器方法直接传入必需的参数。

目前,由于“上下文”仍在HomeController下运行,因此无法尝试解析视图文件夹。

我想我要去的地方就是试图将ASP.NET MVC简化为FrontContoller

有什么想法吗?

修改

最后,我们必须将所有内容序列化为一个会话并使用它。遗憾,但我听说MVC2将支持将对象序列化为ViewState。

4 个答案:

答案 0 :(得分:3)

如果您希望在点击“索引”操作时显示“数量:100”,为什么不直接呈现相应的视图:

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

答案 1 :(得分:2)

我认为最好使用。

return RedirectToAction("Controller", "Action")

但是我猜你想维持网址首页/索引。 如果您正在查看FrontController模式,那么您应该研究编写一个继承自DefaultControllerFactory的Custom ControllerFactory,然后重写CreateController方法。 您可以使用以下代码注册您的工厂。

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

在Controller工厂中,您可以访问RequestContext,因此您可以根据需要更改RouteData并委派给正确的控制器。

你当然可以为Home / Index设置一个自定义路由,转到OtherController.ShowNumberOfThings()

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

答案 2 :(得分:1)

另一种方法是使用部分视图

而不是~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

答案 3 :(得分:0)

另一种可能性(类似于部分视图)是使用Html.RenderAction。这允许使用不同的视图模型类和单独的控制器方法。

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