I want to output two different views (one as a string that will be sent as an email), and the other the page displayed to a user.
Is this possible in ASP.NET MVC beta?
I've tried multiple examples:
1. RenderPartial to String in ASP.NET MVC Beta
If I use this example, I receive the "Cannot redirect after HTTP headers have been sent.".
2. MVC Framework: Capturing the output of a view
If I use this, I seem to be unable to do a redirectToAction, as it tries to render a view that may not exist. If I do return the view, it is completely messed up and doesn't look right at all.
Does anyone have any ideas/solutions to these issues i have, or have any suggestions for better ones?
Many thanks!
Below is an example. What I'm trying to do is create the GetViewForEmail method:
public ActionResult OrderResult(string ref)
{
    //Get the order
    Order order = OrderService.GetOrder(ref);
    //The email helper would do the meat and veg by getting the view as a string
    //Pass the control name (OrderResultEmail) and the model (order)
    string emailView = GetViewForEmail("OrderResultEmail", order);
    //Email the order out
    EmailHelper(order, emailView);
    return View("OrderResult", order);
}
Accepted answer from Tim Scott (changed and formatted a little by me):
public virtual string RenderViewToString(
    ControllerContext controllerContext,
    string viewPath,
    string masterPath,
    ViewDataDictionary viewData,
    TempDataDictionary tempData)
{
    Stream filter = null;
    ViewPage viewPage = new ViewPage();
    //Right, create our view
    viewPage.ViewContext = new ViewContext(controllerContext, new WebFormView(viewPath, masterPath), viewData, tempData);
    //Get the response context, flush it and get the response filter.
    var response = viewPage.ViewContext.HttpContext.Response;
    response.Flush();
    var oldFilter = response.Filter;
    try
    {
        //Put a new filter into the response
        filter = new MemoryStream();
        response.Filter = filter;
        //Now render the view into the memorystream and flush the response
        viewPage.ViewContext.View.Render(viewPage.ViewContext, viewPage.ViewContext.HttpContext.Response.Output);
        response.Flush();
        //Now read the rendered view.
        filter.Position = 0;
        var reader = new StreamReader(filter, response.ContentEncoding);
        return reader.ReadToEnd();
    }
    finally
    {
        //Clean up.
        if (filter != null)
        {
            filter.Dispose();
        }
        //Now replace the response filter
        response.Filter = oldFilter;
    }
}
Example usage
Assuming a call from the controller to get the order confirmation email, passing the Site.Master location.
string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);
 
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    