1

I have been experimenting with rendering an view to a string using methods outlines here:

Render a view as a string

The issue is that I need to call my controller action which does not happen when calling View.Render.

var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
viewResult.View.Render(viewContext, sw);

My question is, how can I call RenderAction on an arbitrary controller passing in a route? I am trying to composite together the results of a number of partial views into a single result which will get passed back to the browser.

My code so far. Works except that the action method is not called.

    public static string RenderPartialViewToString(this Controller controller, string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = controller.ControllerContext.RouteData.GetRequiredString("action");

        controller.ViewData.Model = model;

        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
            var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }



        var route = new RouteData();
        route.Values.Add("controller", "Test1");
        route.Values.Add("action", "Index");

        var controller1 = new Test1Controller();

        var controllerContext = new ControllerContext(new RequestContext(this.ControllerContext.HttpContext, route), controller1);
        controller1.ControllerContext = controllerContext;
        var viewString = controller1.RenderPartialViewToString("~/Views/Test1/Index.cshtml", (object)model);

My goal is to create a simple CMS system that composites together the results of a number of controller actions/views and outputs them into a layout.

I have a primary controller action that retrieves a page description from the database. The code loops over a list of other controllers and calls their actions which results in a dynamic object model and a list of partial html snippets that is handed off to a custom WebViewPage.

Community
  • 1
  • 1
rboarman
  • 8,248
  • 8
  • 57
  • 87

1 Answers1

0

I'm somewhat unsure of what you're trying to accomplish. However, that aside RenderPartialViewToString is an extension method. To use within a controller action you could do something as simple as this:

var result = this.RenderPartialViewToString("Index", model)

Where model is the strongly typed model used within the "Index" view. If for example you were wanting to render a view to string to use within a JSON action you could return a JSONResult with:

return new JsonResult
           {
               JsonRequestBehavior = JsonRequestBehavior.AllowGet,
               Data = new {html = this.RenderPartialViewToString("Index", model)}
           };
Jesse
  • 8,223
  • 6
  • 49
  • 81
  • This method only works under the current controller's context. When I create a fake context and call the code, it does not call the controller's action. It only renders the view. – rboarman Mar 20 '12 at 16:34
  • @rboarman is your question about unit testing a controller action that makes use of renderpartialviewtostring? – Jesse Mar 23 '12 at 05:24