views:

730

answers:

1

I have an action method, and depending on what is passed to it, I want to redirect to another action in another controller. The action and controller names are determined at run time.

If I return RedirectToAction(), it will force a redirect and change the URL in the browser. What I would like is something like TransferToAction() that can transfer processing of the current request to another action, without doing a redirect. I seem to remember a method behaving like this in earlier previews, but I can't seem to find it in the RC of ASP.NET MVC.

Do you know how I would do this?

UPDATE

I added the following route:

routes.MapRoute(
    "PageRouter",
    "{site}/{*url}",
    new { controller = "PageRouter", 
       action = "RoutePage", site = "", url = "" }
);

And the PageRouter controller action RoutePage:

public ActionResult RoutePage(string site, string url)
{
    var controller = new HomeController {ControllerContext = ControllerContext};
    controller.RouteData.Values["controller"] = "Home";
    controller.RouteData.Values["action"] = "Index";

    return controller.Index(site, url);
}

I had to set the controller and action in RouteData for the Home Index view to be rendered. Otherwise, it would look for an Index view in PageRouterController.

I still need to figure out how to create a controller and its action knowing only their names. e.g. I'd like to be able to just call something like this:

public ActionResult RoutePage(string site, string url)
{
    return InvokeAction("Home", "Index");
}

What should go in InvokeAction() ? Do I need to pass it any context?

+2  A: 

You should be able to just call the other method directly and, assuming that it returns a ViewResult, it will render that view in response to the request and the url will not change. Note, you'll be responsible for making sure that all of the data that the other method needs is available to it. For example if your other method requires some form parameters that weren't provided, you may need to construct a suitable FormCollection and set the ValueProvider of the controller to a ValueProvider based on your FormCollection. Likewise with any arguments required by the method.

tvanfosson
So I'll have to use reflection to call the action method? I don't know the name of the action or controller I'm redirecting to until run time.
Lance Fisher
Also, what about the controller context? This method doesn't seem to be working for me.
Lance Fisher
The controller context will be the same. What seems to not be working? Maybe you could post some code.
tvanfosson
I added some code of what I have so far. Thanks.
Lance Fisher
I'm unsure of what you are trying to accomplish. I was assuming that you were redirecting to another action in the same controller, but you seem to be adding your own routing layer on top of the routing in MVC. I'm not sure you can do what you want and I'm not sure why you would want to.
tvanfosson
This suggestion would work OK if the called action was in the same controller, but would not work in all cases if it was in a different controller; the Initialize, for example, would not run.
Craig Stuntz
@Craig -- yes, I was assuming it was the same controller -- for example, List and Index actions map to the same view but you don't want to redirect. It never occurred to me to route to a different controller's actions without doing a redirect. Somehow that just seems "broken" to me.
tvanfosson
I agree, tvanfosson; a redirect is correct.
Craig Stuntz