【问题标题】:How can I Call Controller and View by string as result for ActionResult?如何通过字符串调用控制器和视图作为 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被清除,我不希望它发生,我也不想重定向,还有其他方法吗?

【问题讨论】:

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

标签: c# asp.net asp.net-mvc


【解决方案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://stackoverflow.com/a/24475934/5485841

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-09
      • 1970-01-01
      • 2016-11-24
      相关资源
      最近更新 更多