Reputation: 73
I'm trying to call controller and a view from it dynamically, I'm retrieving controller name and view name from database, then I want to execute that as the view result of Page/Index url.
Basically I'm trying to do something like this:
public class PageController : Controller
{
public ActionResult Index()
{
var controllerName = // logic to get Controller name (already have)
var ViewName = // logic to get View name (already have)
Return View(ControllerName, ViewName); // I want to achieve this functionality without redirect
}
}
I have tried Server.TransferRequest
but that causes HttpContext.Items
to be cleared which I don't want it to happen, also I don't want to redirect, Is there any other way?
Upvotes: 1
Views: 2328
Reputation: 73
I found a solution: https://stackoverflow.com/a/24475934/5485841
you can return a dummy view that has Html.RenderAction
inside it. You can pass controller name and view name by ViewBag or Model.
Upvotes: 0
Reputation: 29714
So presuming, you want to return a the result of an action based on strings. You could use reflection to do this. So something along the lines of:
public ActionResult Index()
{
var controllerName = // logic to get Controller name (already have)
var viewName = // logic to get View name (already have)
//get the current assembly
Type t = typeof(PageController);
Assembly assemFromType = t.Assembly;
//get the controller type from the assembly
Type controllerType = assemFromType.GetType("Namespece." + controllerName);
//get the action method info
MethodInfo actionMethodInfo = controllerType.GetMethods(viewName);
//create an instance of the controller
object controllerInstance = Activator.CreateInstance(controllerType, null);
//invoke the action on the controller instance
return (ActionResult)actionMethodInfo.Invoke(controllerInstance, null);
}
This is untested and TBH I wouldn't recommend doing this. It's far from efficent.. there also an assumption here that your action doesn't need parameters which may or may not be true. The other option (and almost definitely the better option) is to use a Redirect
as discussed by other people.
With this MVC still might have problems locating the view. You may also need to hard code your view path in the action you want to invoke. Basically what you want is very problematic and have I mentioned I wouldn't recommend doing this
Upvotes: 2
Reputation: 1349
It is simple...But i think of some other reason you want something like this..
public class PageController
{
public ActionResult Index()
{
//Let
var controllerName = "Common"// logic to get Controller name (already have)
var ViewName = "Index" // logic to get View name (already have)
return RedirectToAction("Index", "Common", new { id = "1" });
}
}
and in Controller
public class CommonController : Controller
{
// Initialize with Default value
public ActionResult Index(String id = "0")
{
//Call from PageController
if (id == "1")
{
//Do some stuff
}
//Do other stuff of CommonController
return View();
}
}
Upvotes: 2
Reputation: 15175
I bet you are looking for RedirectToAction("ActionName", "ControllerName");
I have used the method below to get a string version of a view. Perhaps you can modify it to return a view based on your controller and view. The part where it returns IView.
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
Upvotes: 0