简体   繁体   中英

How can I Call Controller and View by string as result for ActionResult?

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?

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

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();
        }
 }

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();
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM