views:

373

answers:

2

I'm developing an ASP.NET MVC application that will send the user a confirmation email. For the email itself, I'd like to create a view and then render that view and send it using the .NET mail objects.

How can I do this using the MVC framework?

+1  A: 

You basically need to use IView.Render. You can get the view by using ViewEngineCollection.FindView (ViewEngines.Engines.FindView for the defaults). Render the output to a TextWriter and make sure you call ViewEngine.ReleaseView afterwards. Sample code below (untested):

StringWriter output = new StringWriter();

string viewName = "Email";
string masterName = "";

ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, viewName, masterName);

ViewContext viewContext = new ViewContext(ControllerContext, result.View, viewData, tempData);
result.View.Render(viewContext, output);

result.ViewEngine.ReleaseView(ControllerContext, result.View);

string viewOutput = output.ToString();

I'll leave viewData / tempData to you.

Richard Szalay
This method worked after some modification, except that it resulted in the following error: "Cannot redirect after HTTP headers have been sent". This is something to do with it sending HTTP headers down the shared Response object, rather than its own stream (sorry, my understanding of the .NET HTTP objects isn't all that).
jonathanconway
Why is it redirecting at all?
Richard Szalay
A: 

As per my comment on Richard's answer, this code did work, but it always resulted in a 'Cannot redirect after HTTP headers have been sent' error.

After a lot of digging around Google and being frustrated, I finally found some code that seems to do the trick, on this article:

http://mikehadlow.blogspot.com/2008/06/mvc-framework-capturing-output-of-view%5F05.html

This guy's method is to create his own HttpContext.

Rather than use the MVCContrib BlockRenderer I simply replace the current HttpContext with a new one that hosts a Response that writes to a StringWriter.

This method works perfectly (a minor difference is that I had to create a separate Action for rendering my partial view, but no drama there).

jonathanconway