Email as a view
I've been in some discussion recently about where email (notifications, etc...) should be sent in an ASP.NET MVC application. My nemesis grin argues that it only makes sense that the email should be sent from the controller.
I argue that an email is simply an alternate or augmented view through a differe开发者_运维百科nt channel. Much like I would download a file as the payload of an ActionResult, the email is simply delivered through a different protocol.
I've worked an extension method that allows me to do the following:
<% Html.RenderEmail(model.FromAddress, model.ToAddress, model.Subject); %>
which I actually include within my the view that is displayed on the screen. The beauty is that, based on convention, if I call RenderEmail from a parent view named MyView.ascx, I attempt to render the contents of a view named MyViewEmail.ascx, unless it is not found, in which case I simply email a copy of parent view.
It certainly does make it testable (I still have an ISMTPService injected for testing), I wondered if anyone had any thoughts on whether or not this breaks from good practice. In use it has been extremely handy when we needed to easily send an email or modify the contents of the emailed results vs the browser rendered results.
Thanks,
Hal
Your "nemesis" is correct.
The job of the view is to send HTML to the client, and nothing else. It has no business sending email.
You should send the email inside the controller.
If you want to render a view to the email, you can render it like this:
var viewData = new ViewDataDictionary<T>(data);
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, "ViewName");
using (var writer = new StringWriter(CultureInfo.InvariantCulture)) {
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, viewData, new TempDataDictionary(), writer);
viewResult.View.Render(viewContext, writer);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return writer.ToString();
}
Did you take a look at MvcMailer? See the NuGet package here and the project documentation
Hope it helps!
A Conversational Answer
I totally understand your idea. It may be instructional to take step back from Microsoft's MV-whatever framework and look at a more pristine MVC setup.
If representational state can be anything you desire, then, in a web application, a View does not just have to send HTML. In fact, if one were processing an incoming HTTP Accept:
header, it would contain media types that could help you determine which representational state to reply with.
In the case of an XMLHttpRequest via JavaScript, the Accept:
header might say application/json
or application/xml
. The client would be expecting JSON or XML. Sending HTML would be wrong.
Now, since e-mail is not sent directly to a client user-agent (after form submission), it is more of a side effect of processing the form than a representational state that you must conform and reply with. In a more "pure" MVC environment, e-mail would be sent by the Model as a service. The Controller would not be involved in sending email, as this is not where business logic for the application should reside.
Nonetheless, your point that email (SMTP instead of HTTP) could be at least a secondary view has a certain resonance. However, this may require (depending on the application) passing a significant amount of data from the Model to the hypothetical "EmailView". If that is no obstacle, then the issue would be the need to update the Primary View (the web page) and send e-mail with the Secondary View while the Model sits in idle.
Thus, it is highly practical to allow the Model to send e-mail as part of business logic. Then, allow the View to update the user-agent. This is why I say sending e-mail is more a side-effect than a true View.
However, point taken about SMTP. It is just that the Accept:
header for a basic web-application will, for all practical purposes, almost never say application/batch-SMTP
.
What if you were writing server-side e-mail applications? Yes, then you would probably see incoming application/batch-SMTP
all of the time. :-)
IANA: Media Types
精彩评论