Get html from MVC 4 view into a string

后端 未结 3 1390
醉酒成梦
醉酒成梦 2020-12-08 05:12

I am trying to use the accepted answer from this question.

It seems that it will be exactly what i am looking for, but i have a problem. I don\'t know how to actuall

相关标签:
3条回答
  • 2020-12-08 05:53

    You can create a base controller which obviously extends a controller and use above function in the base controller and other controller which extends this base controller will be able to use it. However the ControllerContext must be used as

    Request.RequestContext
    

    And Hence your BaseController will be like

    public class BaseController: Controller
    {
    //your function here
    }
    

    And your ToHtml() function will be

    protected virtual string ToHtml(string viewToRender, ViewDataDictionary viewData )
    {
       var controllerContext=Request.RequestContext;
       var result = ViewEngines.Engines.FindView(controllerContext, viewToRender, null);
    
       StringWriter output;
       using (output = new StringWriter())
       {
          var viewContext = new ViewContext(controllerContext, result.View, viewData, controllerContext.Controller.TempData, output);
          result.View.Render(viewContext, output);
          result.ViewEngine.ReleaseView(controllerContext, result.View);
       }
    
       return output.ToString();
    }
    

    And on using the base controller

    public class MyController: BaseController
    {
    //ToHtml(...);
    }
    
    0 讨论(0)
  • 2020-12-08 05:53

    This is pretty much a copy of dav_i's post except that you have a model with strong typing and also the ability of producing partial views:

    Rather than inherit Controller which means you have to remember to implement this every time, or inherit from a CustomControllerBase, which means you have to remember to inherit every time - simply make an extension method:

    public static class ControllerExtensions
    {
        public static string RenderView<TModel>(this Controller controller, string viewName, TModel model, bool partial = false)
        {
            var controllerContext = controller.ControllerContext;
            controllerContext.Controller.ViewData.Model = model;
    
            // To be or not to be (partial)
            var viewResult = partial ? ViewEngines.Engines.FindPartialView(controllerContext, viewName) : ViewEngines.Engines.FindView(controllerContext, viewName, null);
    
            StringWriter stringWriter;
    
            using (stringWriter = new StringWriter())
            {
                var viewContext = new ViewContext(
                    controllerContext,
                    viewResult.View,
                    controllerContext.Controller.ViewData,
                    controllerContext.Controller.TempData,
                    stringWriter);
    
                viewResult.View.Render(viewContext, stringWriter);
                viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View);
            }
    
            return stringWriter.ToString();
        }
    }
    

    Then within your Controller you can call like this (for a full view):

    this.RenderView("ViewName", model);
    

    That means you will get the doctype and the HTML element etc too. For partial view use:

    this.RenderView("ViewName", model, true);
    
    0 讨论(0)
  • 2020-12-08 05:56

    Rather than inherit Controller which means you have to remember to implement this every time, or inherit from a CustomControllerBase, which means you have to remember to inherit every time - simply make an extension method:

    public static class ControllerExtensions
    {
        public static string RenderView(this Controller controller, string viewName, object model)
        {
            return RenderView(controller, viewName, new ViewDataDictionary(model));
        }
    
        public static string RenderView(this Controller controller, string viewName, ViewDataDictionary viewData)
        {
            var controllerContext = controller.ControllerContext;
    
            var viewResult = ViewEngines.Engines.FindView(controllerContext, viewName, null);
    
            StringWriter stringWriter;
    
            using (stringWriter = new StringWriter())
            {
                var viewContext = new ViewContext(
                    controllerContext,
                    viewResult.View,
                    viewData,
                    controllerContext.Controller.TempData,
                    stringWriter);
    
                viewResult.View.Render(viewContext, stringWriter);
                viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View);
            }
    
            return stringWriter.ToString();
        }
    }
    

    Then within your Controller you can call like this:

    this.RenderView("ViewName", model);
    
    0 讨论(0)
提交回复
热议问题