Hilmi
Hilmi

Reputation: 3441

Render partial view as string

I know this looks like a duplicate question, but please read the whole question before marking it as duplicate.

First of all, I'm simulating the windows service in my ASP web application to send weekly emails, so in Global.asax I'm running my function that will send the emails.

Now the emails content is in HTML and I want to render the views to get the content. The problem is that in my function, I don't have any of the following :

I tried to use the RazorEngine to use the partial as a template by reading the file then using Razor.Parse() method. But I faced a lot of problems from this approach, because nothing is included in the template. What I mean is: it keeps telling me that The name "Html" does not exist in the current context OR 'CompiledRazorTemplates.Dynamic.becdccabecff' does not contain a definition for 'Html' even if I include the System.Web.Mvc.Html.

how can I solve this issue?.

Upvotes: 0

Views: 838

Answers (2)

Anup Sharma
Anup Sharma

Reputation: 2083

Without using 3rd party library, one can use this method to generate string of view in Global.asax.cs file

public class EmptyController : Controller { }

public string GetView(string viewName)
   {
   //Create an instance of empty controller
   Controller controller = new EmptyController();

   //Create an instance of Controller Context
   var ControllerContext = new ControllerContext(Request.RequestContext, controller);

   //Create a string writer
   using (var sw = new StringWriter())
   {
      //get the master layout
      var master = Request.IsAuthenticated ? "_InternalLayout" : "_ExternalLayout";

      //Get the view result using context controller, partial view and the master layout
      var viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, master);

      //Crete the view context using the controller context, viewResult's view, string writer and ViewData and TempData
      var viewContext = new ViewContext(ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);

      //Render the view in the string writer
      viewResult.View.Render(viewContext, sw);

      //release the view
      viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);

      //return the view stored in string writer as string
      return sw.GetStringBuilder().ToString();
   }
}

Upvotes: 0

Kambiz Shahim
Kambiz Shahim

Reputation: 2590

I think the best approach is assuming you developed a real NT service and use HttpClient to send a http request to your partial view and receive the response as string and use it to make up your email. However, you can have HttpContext in RunScheduledTasks method by making some changes in Scheduler class.

 public delegate void Callback();

to

 public delegate void Callback(HttpContext httpContext);

add cache.Current_HttpContext = HttpContext.Current; to the Run method

    public static void Run(string name, int minutes, Callback callbackMethod)
    {
        _numberOfMinutes = minutes;

        CacheItem cache = new CacheItem();
        cache.Name = name;
        cache.Callback = callbackMethod;
        cache.Cache = HttpRuntime.Cache;
        cache.LastRun = DateTime.Now;
        cache.Current_HttpContext = HttpContext.Current;
        AddCacheObject(cache);
    }

change CacheCallback to

    private static void CacheCallback(string key, object value, CacheItemRemovedReason reason)
    {
        CacheItem obj_cache = (CacheItem)value;
        if (obj_cache.LastRun < DateTime.Now)
        {
            if (obj_cache.Callback != null)
            {
                obj_cache.Callback.Invoke(obj_cache.Current_HttpContext);
            }
            obj_cache.LastRun = DateTime.Now;
        }
        AddCacheObject(obj_cache);
    }

Edited: How to use HttpClient

  HttpClient client = new HttpClient();
  HttpResponseMessage response = await client.GetAsync("http://localhost/controller/action/");
  response.EnsureSuccessStatusCode();
  string responseBody = await response.Content.ReadAsStringAsync();

Upvotes: 1

Related Questions