Reputation: 3441
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 :
Controller
ControllerContext
HttpContext
RoutData
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
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
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