如何通过字符串调用控制器和视图作为 ActionResult 的结果?

Posted

技术标签:

【中文标题】如何通过字符串调用控制器和视图作为 ActionResult 的结果?【英文标题】:How can I Call Controller and View by string as result for ActionResult? 【发布时间】:2016-09-19 18:48:18 【问题描述】:

我正在尝试动态调用控制器和视图,我正在从数据库中检索控制器名称和视图名称,然后我想将其作为页面/索引 url 的视图结果执行。

基本上我正在尝试做这样的事情:

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

    


我尝试过Server.TransferRequest,但这会导致HttpContext.Items被清除,我不希望它发生,我也不想重定向,还有其他方法吗?

【问题讨论】:

您是否只是想获得另一个控制器和操作的结果,而不需要重定向? 这可能会帮助你得到答案:***.com/questions/18248547/… @TiesonT。没错 您是否必须在您的 PageController 中实现该逻辑?你不能使用 Global.asax 吗? 我需要一个来自控制器名称和视图名称的视图结果,该视图结果应该是页面/索引,所以它基本上就像一个重定向但没有实际的重定向,所以浏览器不会得到 302状态码 【参考方案1】:

这很简单......但我想你想要这样的一些其他原因......

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" ); 

    


在控制器中

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

【讨论】:

【参考方案2】:

所以假设,你想返回一个基于字符串的动作的结果。你可以使用反射来做到这一点。所以大致如下:

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

这是未经测试的,TBH 我不建议这样做。这远非有效..这里还假设您的操作不需要可能为真或不为真的参数。另一种选择(几乎肯定是更好的选择)是使用Redirect 作为discussed by other people。

使用此 MVC 仍然可能无法定位视图。您可能还需要在要调用的操作中对视图路径进行硬编码。基本上你想要的很成问题,我是否提到过我不建议这样做

【讨论】:

谢谢,我会试试并报告 由于某种原因,我收到错误消息:“未找到视图'索引'或其主控或视图引擎不支持...”。我进入调试模式,“索引”甚至不是我传递的 ViewName,这很奇怪,但感谢您的帮助 是的,我确实这么认为。问题是它不知道使用哪个视图。您可以在子操作中硬编码视图路径。 TBH,你真的需要为这种事情使用重定向。这将很难维护【参考方案3】:

我打赌你正在寻找RedirectToAction("ActionName", "ControllerName");

我使用下面的方法来获取视图的字符串版本。也许您可以修改它以根据您的控制器和视图返回一个视图。返回 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();
    

【讨论】:

对不起,我忘了提到我不想在问题中重定向 我所拥有的只是一个呈现视图的功能,而不是请求的服务端【参考方案4】:

我找到了解决办法:https://***.com/a/24475934/5485841

您可以返回一个包含html.RenderAction 的虚拟视图。您可以通过 ViewBag 或 Model 传递控制器名称和视图名称。

【讨论】:

以上是关于如何通过字符串调用控制器和视图作为 ActionResult 的结果?的主要内容,如果未能解决你的问题,请参考以下文章

从局部视图中对控制器的 AJAX 调用

如何在 Spring MVC 中使用 AJAX 渲染视图

当模态视图控制器被解除时如何调用函数

尝试使用 ajax 调用将 urdu 字符串视图发送到控制器,但它在控制时始终为空

如何通过 didselectrow 手动点击按钮时推送到详细视图控制器;再次返回,然后作为数据源数组的计数推送?

如何通过控制器将两个不同模型的值作为 Laravel 8 中的单个返回变量传递给视图文件