title: Render partial view through custom taghelper
body: <p>I've searched everywhere, what I want is basically a RenderViewToString for MVC6 that does NOT use the context of a controller or action.</p>
  
  <p>Since custom TagHelpers go into their own class, these context's won't be available.</p>
  
  <p>Currently I have the following code, I'd very much like to put the html in a Razor View, cause this is unacceptable lol.</p>
  
  <pre><code>public class WindowTagHelper : TagHelper
  {
      public string Title { get; set; }
      public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
      {
          var preContent = await output.GetChildContentAsync();      
          var id = context.UniqueId;
          output.TagName = "div";
          output.Attributes["id"] = id;
          output.Attributes["class"] = "window";
          output.TagMode = TagMode.StartTagAndEndTag;
  
          var windowControls = new StringBuilder();
          windowControls.Append("&lt;div class=\"window-controls\"&gt;");
          windowControls.Append("&lt;ul class=\"window-icon-list\"&gt;");  
  
          var minimizeIcon = "&lt;li class=\"control-icon\"&gt;&lt;a data-window-id=\"{0}\" class=\"control-icon-minimize\" href=\"#\" data-toggle=\"tooltip\" title=\"Minimize Window\"&gt;&lt;div class=\"fa fa-minus\"&gt;&lt;/div&gt;&lt;/a&gt;&lt;/li&gt;".InjectWith(id);
          var maximizeIcon = "&lt;li class=\"control-icon\"&gt;&lt;a data-window-id=\"{0}\" class=\"control-icon-maximize\" href=\"#\" data-toggle=\"tooltip\" title=\"Maximize Window\"&gt;&lt;div class=\"fa fa-square-o\"&gt;&lt;/div&gt;&lt;/a&gt;&lt;/li&gt;".InjectWith(id);
          var closeIcon = "&lt;li class=\"control-icon\"&gt;&lt;a data-window-id=\"{0}\" class=\"control-icon-close\" href=\"#\" data-toggle=\"tooltip\" title=\"Close Window\"&gt;&lt;div class=\"fa fa-close\"&gt;&lt;/div&gt;&lt;/a&gt;&lt;/li&gt;".InjectWith(id);
  
          windowControls.Append(minimizeIcon);
          windowControls.Append(maximizeIcon);
          windowControls.Append(closeIcon);
          windowControls.Append("&lt;/ul&gt;");
          windowControls.Append("&lt;/div&gt;");
  
          var content = new StringBuilder();
          content.AppendFormat("&lt;div class=\"window-title\"&gt;{0}{1}&lt;/div&gt;", windowControls.ToString(), Title);
          content.Append(preContent.GetContent());
          output.Content.AppendHtml(content.ToString());          
      }
  }
  </code></pre>
  
  <p>Following method does not work, it throws an exception and injecting ICompositeViewEngine as service requires a controller/action context.</p>
  
  <pre><code>public string RenderPartialViewToString(string viewName, object model)
  {
      if (string.IsNullOrEmpty(viewName))
          viewName = ActionContext.ActionDescriptor.Name;
  
      ViewData.Model = model;
  
      using (StringWriter sw = new StringWriter())
      {
          var engine = Resolver.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
          ViewEngineResult viewResult = engine.FindPartialView(ActionContext, viewName);
  
          ViewContext viewContext = new ViewContext(ActionContext, viewResult.View, ViewData, TempData, sw,new HtmlHelperOptions());
  
          var t = viewResult.View.RenderAsync(viewContext);
          t.Wait();
  
          return sw.GetStringBuilder().ToString();
      }
  }
  </code></pre>