1

I have a situation where I need to redirect to an ASP.NET MVC action in a different controller. I can't use RedirectToAction because I must POST the action's parameters to keep them out of the URL.

I attempted to instantiate and call the other controller's action directly like this:

OtherController myOtherController = new OtherController();
myOtherController.ControllerContext = new ControllerContext(this.ControllerContext.RequestContext, myOtherController);
return await myOtherController.Edit(myGuid);

When I do this, the other controller's code executes, but I end up with this error:

The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.OtherModel_BBCEF7C9378F4C4F097CC08FA2E508B8BD8D865E33093E31959919087A31348E', but this dictionary requires a model item of type 'ThisModel'.

Does anyone know if I can get this working using the current approach? Assuming I must use an HTTP POST action and cannot have parameters in the URL, is there a different approach that you would recommend to achieve this result (other than combining the controllers)?
Edit:
Note that I don't think I can post directly from the client because I would need to nest Html.BeginForm.

3
  • Note that I don't think I can post directly from the client because I would need to nest Html.BeginForm. Commented Oct 13, 2016 at 18:27
  • So the RouteValues in a call to RedirectToAction will not work here for you? Commented Oct 14, 2016 at 15:17
  • If the result is parameters in the URL, no. The mandate coming down is those are not acceptable. Commented Oct 17, 2016 at 12:20

2 Answers 2

1

You should really just be using RedirectToAction to push the browser to the action you want instead of trying to do it like this. As you can see from @Andrei Olariu code a lot of things happen under the hood during the construction of your controller (DI then context and parameter mappings) that really shouldn't be done manually and can easily be screwed up leading to hours wasted wondering why certain things are not behaving as expected.

Sign up to request clarification or add additional context in comments.

1 Comment

I've been given a mandate that parameters in the URL are unacceptable. I need to be sure to explore all alternatives before I push back. You points are appreciated and valid.
0

I hope I understood what you're trying to do. This is what I'm successfully using to execute an action on a different controller.

private void ExecuteErrorAction(string action, HttpContextWrapper httpContext, Exception exception)
{
    var routeData = new RouteData();
    routeData.Values["controller"] = "Error";
    routeData.Values["action"] = action;
    routeData.Values["exception"] = exception;

    IController errorController = DependencyResolver.Current.GetService<ErrorController>();
    var context = new RequestContext(httpContext, routeData);
    errorController.Execute(context);
}

I think that in your case this could look like:

private void ExecuteOtherAction(string myGuid, HttpContextWrapper httpContext)
{
    var routeData = new RouteData();
    routeData.Values["controller"] = "OtherController";
    routeData.Values["action"] = "Edit";
    routeData.Values["myGuid"] = myGuid;

    IController otherCntroller = DependencyResolver.Current.GetService<OtherController>();
    var context = new RequestContext(httpContext, routeData);
    otherCntroller.Execute(context);
}

This is assuming that your Edit action on the OtherController takes a string called myGuid as a parameter.

Let me know if this helps.

5 Comments

Thanks. How does this work in the original controller action? I need to return a model to the view associated with the "new" action in OtherController.
You can call ExecuteOtherAction from your original controller and then return a new EmptyResult(). When you call Execute that will take over and whatever is returned will be what your OtherController.Edit action returns. I am using this method but I'm calling it from Global.asax; it does work from inside a controller though (like I suggested, but it looks a bit..ugly). What does your OtherController.Edit action return?
The view returns a custom model that is different than the model used in the original controller. I'll give this a shot and see how it goes. Thanks for the info.
My actions are async, so I get this error on the otherController.Execute line: System.InvalidOperationException: The asynchronous action method 'Edit' returns a Task, which cannot be executed synchronously.
I tried your code and it works for me. The error you're getting suggests that there is a problem during the execution of your other action, which I don't think it's connected to the way you're actually calling it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.