Chcę wygenerować dwa różne widoki (jeden jako ciąg, który zostanie wysłany jako wiadomość e-mail), a drugi stronę wyświetlaną użytkownikowi.
Czy jest to możliwe w programie ASP.NET MVC w wersji beta?
Próbowałem wielu przykładów:
1. Renderuj na łańcuch w ASP.NET MVC Beta
Jeśli użyję tego przykładu, otrzymuję komunikat „Nie można przekierować po wysłaniu nagłówków HTTP”.
2. MVC Framework: Przechwytywanie danych wyjściowych widoku
Jeśli go użyję, wydaje mi się, że nie mogę wykonać operacji redirectToAction, ponieważ próbuje ona renderować widok, który może nie istnieć. Jeśli zwrócę widok, jest on całkowicie popsuty i wcale nie wygląda dobrze.
Czy ktoś ma jakieś pomysły / rozwiązania tych problemów, czy mam jakieś sugestie dotyczące lepszych?
Wielkie dzięki!
Poniżej znajduje się przykład. Próbuję utworzyć metodę GetViewForEmail :
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);
}
Zaakceptowana odpowiedź od Tima Scotta (zmieniona i sformatowana przeze mnie trochę):
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;
}
}
Przykładowe użycie
Przyjęcie połączenia z kontrolera w celu otrzymania wiadomości e-mail z potwierdzeniem zamówienia, przekazanie lokalizacji Site.Master.
string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);