I have a controller called EmailController, which is (you guessed it) responsible for sending emails.
An example of this is that users of my site can "favorite" things, and if some other user does something on one of those "things", then i need to send an email out to all users who "favourited" it. Kind of like an email alert.
The problem is, im not sure how to call my EmailController's action method, from the other action method (which is the HTTP POST for when a user does something).
Normally i would put this kind of operation (emailing) into a service, and the actual emailing logic (SMTP) is in a service, but the EmailController is responsible for setting up the content of the email (e.g the HTML), for which is needs to render a View to a string (hence, it needs a controller context and cannot go into a service).
How can i achieve this?
I can't just use a static helper method, because how can i render the view? I would need to pass the controller context to the method or something.
Example flow:
So at step 3, i need to:
Currently, i have 2/3/4 above in EmailController, so i was hoping to use that.
As a side note, i was hoping to make the emailing asynchronous (since the user who just created some data doesnt care that another user needs to get emailed).
Can anyone give me some advice on how to organize these seperate concerns (submitting data, creating HTML view into string, sending email).
Perhaps a HTML helper or a protected method in a base controller is a better option than a controller?
FYI, here's my "View to string" method (i pulled from another Stack question, and works great):
protected string RenderViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, null);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
You could take a look at the ActionMailer package from nuGet. Then you don't need a seperate controller.