Render View programmatically into a string

前端 未结 3 1492
小鲜肉
小鲜肉 2020-12-30 14:51

I would like to get the html code a view would generate in a string, modify it in my controller, then add it to my JsonResult.

I found code that would do what i\'m t

3条回答
  •  一生所求
    2020-12-30 15:14

    Mike Hadlow blogged about a function called CaptureActionHtml() that does this. I've used it to compose large reports out of smaller, more manageable reports and then pass them around.

    http://mikehadlow.blogspot.com/2008/06/mvc-framework-capturing-output-of-view_05.html

    using System;
    using System.IO;
    using System.Web;
    using System.Web.Mvc;
    
    namespace Suteki.Common.Extensions
    {
        public static class ControllerExtensions
        {
            /// 
            /// Captures the HTML output by a controller action that returns a ViewResult
            /// 
            /// The type of controller to execute the action on
            /// The controller
            /// The action to execute
            /// The HTML output from the view
            public static string CaptureActionHtml(
                this TController controller,
                Func action)
                where TController : Controller
            {
                return controller.CaptureActionHtml(controller, null, action);
            }
    
            /// 
            /// Captures the HTML output by a controller action that returns a ViewResult
            /// 
            /// The type of controller to execute the action on
            /// The controller
            /// The master page to use for the view
            /// The action to execute
            /// The HTML output from the view
            public static string CaptureActionHtml(
                this TController controller,
                string masterPageName,
                Func action)
                where TController : Controller
            {
                return controller.CaptureActionHtml(controller, masterPageName, action);
            }
    
            /// 
            /// Captures the HTML output by a controller action that returns a ViewResult
            /// 
            /// The type of controller to execute the action on
            /// The current controller
            /// The controller which has the action to execute
            /// The action to execute
            /// The HTML output from the view
            public static string CaptureActionHtml(
                this Controller controller,
                TController targetController, 
                Func action)
                where TController : Controller
            {
                return controller.CaptureActionHtml(targetController, null, action);
            }
    
            /// 
            /// Captures the HTML output by a controller action that returns a ViewResult
            /// 
            /// The type of controller to execute the action on
            /// The current controller
            /// The controller which has the action to execute
            /// The name of the master page for the view
            /// The action to execute
            /// The HTML output from the view
            public static string CaptureActionHtml(
                this Controller controller,
                TController targetController, 
                string masterPageName,
                Func action)
                where TController : Controller
            {
                if (controller == null)
                {
                    throw new ArgumentNullException("controller");
                }
                if (targetController == null)
                {
                    throw new ArgumentNullException("targetController");
                }
                if (action == null)
                {
                    throw new ArgumentNullException("action");
                }
    
                // pass the current controller context to orderController
                var controllerContext = controller.ControllerContext;
                targetController.ControllerContext = controllerContext;
    
                // replace the current context with a new context that writes to a string writer
                var existingContext = System.Web.HttpContext.Current;
                var writer = new StringWriter();
                var response = new HttpResponse(writer);
                var context = new HttpContext(existingContext.Request, response) {User = existingContext.User};
                System.Web.HttpContext.Current = context;
    
                // execute the action
                var viewResult = action(targetController);
    
                // change the master page name
                if (masterPageName != null)
                {
                    viewResult.MasterName = masterPageName;
                }
    
                // we have to set the controller route value to the name of the controller we want to execute
                // because the ViewLocator class uses this to find the correct view
                var oldController = controllerContext.RouteData.Values["controller"];
                controllerContext.RouteData.Values["controller"] = typeof(TController).Name.Replace("Controller", "");
    
                // execute the result
                viewResult.ExecuteResult(controllerContext);
    
                // restore the old route data
                controllerContext.RouteData.Values["controller"] = oldController;
    
                // restore the old context
                System.Web.HttpContext.Current = existingContext;
    
                return writer.ToString();
            }
        }
    }
    

提交回复
热议问题