title: Implement MVC ViewRenderer in a .NET console application
body: <p>I added a newsletter feature to my MVC 5 project to send constructed mails to all subscribed users.<br>
  I’ve a class with <code>public async Task&lt;NewsletterLogResult&gt; SendNewsletters(int? id = null, ControllerContext ControllerContext = null)</code> being called from an action <code>public async Task&lt;ActionResult&gt;SendMail(int id)</code><br>
  <code>SendNewsletters</code> implements <code>Viewrenderer</code>, something like this <code>cBody = ViewRenderer.RenderPartialView(ViewRenderer.TemplatePath + "Newsletters/" + record.Newsletter_Template + "Body.cshtml", record, ControllerContext);</code></p>
  
  <pre><code>public class ViewRenderer
  {
      protected ControllerContext Context { get; set; }
  
      public const string TemplatePath = "~/Views/Templates/";
  
      public ViewRenderer(ControllerContext controllerContext = null)
      {
          // Create a known controller from HttpContext if no context is passed
          if (controllerContext == null)
          {
              if (HttpContext.Current != null)
                  controllerContext = CreateController&lt;EmptyController&gt;().ControllerContext;
              else
                  throw new InvalidOperationException(
                      "ViewRenderer must run in the context of an ASP.NET Application and requires HttpContext.Current to be present.");
          }
          Context = controllerContext;
      }
  
      public string RenderViewToString(string viewPath, object model = null)
      {
          return RenderViewToStringInternal(viewPath, model, false);
      }
  
      public void RenderView(string viewPath, object model, TextWriter writer)
      {
          RenderViewToWriterInternal(viewPath, writer, model, false);
      }
  
      public string RenderPartialViewToString(string viewPath, object model = null)
      {
          return RenderViewToStringInternal(viewPath, model, true);
      }
  
      public void RenderPartialView(string viewPath, object model, TextWriter writer)
      {
          RenderViewToWriterInternal(viewPath, writer, model, true);
      }
  
      public static string RenderView(string viewPath, object model = null,
                                      ControllerContext controllerContext = null)
      {
          ViewRenderer renderer = new ViewRenderer(controllerContext);
          return renderer.RenderViewToString(viewPath, model);
      }
  
      public static void RenderView(string viewPath, TextWriter writer, object model,
                                      ControllerContext controllerContext)
      {
          ViewRenderer renderer = new ViewRenderer(controllerContext);
          renderer.RenderView(viewPath, model, writer);
      }
  
      public static string RenderView(string viewPath, object model,
                                      ControllerContext controllerContext,
                                      out string errorMessage)
      {
          errorMessage = null;
          try
          {
              ViewRenderer renderer = new ViewRenderer(controllerContext);
              return renderer.RenderViewToString(viewPath, model);
          }
          catch (Exception ex)
          {
              errorMessage = ex.GetBaseException().Message;
          }
          return null;
      }
  
      public static void RenderView(string viewPath, object model, TextWriter writer,
                                      ControllerContext controllerContext,
                                      out string errorMessage)
      {
          errorMessage = null;
          try
          {
              ViewRenderer renderer = new ViewRenderer(controllerContext);
              renderer.RenderView(viewPath, model, writer);
          }
          catch (Exception ex)
          {
              errorMessage = ex.GetBaseException().Message;
          }
      }
  
      public static string RenderPartialView(string viewPath, object model = null,
                                              ControllerContext controllerContext = null)
      {
          ViewRenderer renderer = new ViewRenderer(controllerContext);
          return renderer.RenderPartialViewToString(viewPath, model);
      }
  
      public static void RenderPartialView(string viewPath, TextWriter writer, object model = null,
                                              ControllerContext controllerContext = null)
      {
          ViewRenderer renderer = new ViewRenderer(controllerContext);
          renderer.RenderPartialView(viewPath, model, writer);
      }
  
      protected void RenderViewToWriterInternal(string viewPath, TextWriter writer, object model = null, bool partial = false)
      {
          // first find the ViewEngine for this view
          ViewEngineResult viewEngineResult = null;
          if (partial)
              viewEngineResult = ViewEngines.Engines.FindPartialView(Context, viewPath);
          else
              viewEngineResult = ViewEngines.Engines.FindView(Context, viewPath, null);
  
          if (viewEngineResult == null)
              throw new FileNotFoundException();
  
          // get the view and attach the model to view data
          var view = viewEngineResult.View;
          Context.Controller.ViewData.Model = model;
  
          var ctx = new ViewContext(Context, view,
                                      Context.Controller.ViewData,
                                      Context.Controller.TempData,
                                      writer);
          view.Render(ctx, writer);
      }
  
      private string RenderViewToStringInternal(string viewPath, object model,
                                                  bool partial = false)
      {
          // first find the ViewEngine for this view
          ViewEngineResult viewEngineResult = null;
          if (partial)
              viewEngineResult = ViewEngines.Engines.FindPartialView(Context, viewPath);
          else
              viewEngineResult = ViewEngines.Engines.FindView(Context, viewPath, null);
  
          if (viewEngineResult == null || viewEngineResult.View == null)
          {
              //throw new FileNotFoundException(Resources.ViewCouldNotBeFound);
              throw new Exception("Can't find view.");
          }
  
          // get the view and attach the model to view data
          var view = viewEngineResult.View;
          Context.Controller.ViewData.Model = model;
  
          string result = null;
  
          using (var sw = new StringWriter())
          {
              var ctx = new ViewContext(Context, 
                                        view,
                                        Context.Controller.ViewData,
                                        Context.Controller.TempData,
                                        sw);
              view.Render(ctx, sw);
              result = sw.ToString();
          }
  
          return result;
      }
  
      public static T CreateController&lt;T&gt;(RouteData routeData = null, params object[] parameters)
                  where T : Controller, new()
      {
          // create a disconnected controller instance
          T controller = (T)Activator.CreateInstance(typeof(T), parameters);
  
          // get context wrapper from HttpContext if available
          HttpContextBase wrapper = null;
          if (HttpContext.Current != null)
              wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
          else
              throw new InvalidOperationException(
                  "Can't create Controller Context if no active HttpContext instance is available.");
  
          if (routeData == null)
              routeData = new RouteData();
  
          // add the controller routing if not existing
          if (!routeData.Values.ContainsKey("controller") &amp;&amp; !routeData.Values.ContainsKey("Controller"))
              routeData.Values.Add("controller", controller.GetType().Name
                                                          .ToLower()
                                                          .Replace("controller", ""));
  
          controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
          return controller;
      }
  
  }
  
  public class EmptyController : Controller
  {
  }
  </code></pre>
  
  <p>This is working perfectly in MVC.<br>
  Like running a newsletter sending task from a web application is not a good practice, I want to implement this feature in a Windows service. In order to facilitate I’m testing that in a <strong>Consoleapp</strong>, calling from here <code>SendNewsletters</code>.
  But in Consolapp, like in WIndowsService, I don’t have <strong>HttpContext</strong>, so, it’s possible to create a fake HttpContext, preferably with access to MVC routing (my razor view implements routing helpers, <code>url.action</code>)?</p>