Je veux produire deux vues différentes (l'une sous la forme d'une chaîne qui sera envoyée par courriel), et l'autre sous la forme de la page affichée à un utilisateur.
Est-ce possible dans ASP.NET MVC beta ?
J'ai essayé plusieurs exemples :
1. RenderPartial vers String en ASP.NET MVC Beta
Si j'utilise cet exemple, je reçois le message "Cannot redirect after HTTP ont été envoyés".
2. Cadre MVC : Capturer la sortie d'une vue
Si je l'utilise, il semble que je ne puisse pas faire de redirectToAction, car elle tente de rendre une vue qui peut ne pas exister. tente de rendre une vue qui n'existe peut-être pas. Si je renvoie la vue, elle est est complètement désordonnée et n'a pas du tout l'air correcte.
Est-ce que quelqu'un a des idées/solutions à ces problèmes que j'ai, ou a des suggestions pour de meilleures solutions ?
Merci beaucoup !
Vous trouverez ci-dessous un exemple. Ce que j'essaie de faire, c'est de créer l'élément Méthode 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);
}
Réponse acceptée de Tim Scott (modifiée et formatée un peu par moi) :
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;
}
}
Exemple d'utilisation
Supposons un appel du contrôleur pour obtenir l'email de confirmation de la commande, en passant l'emplacement Site.Master.
string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);
2 votes
Comment pouvez-vous utiliser ceci avec une vue, qui est fortement typée ? Par exemple, comment puis-je alimenter un modèle dans la page ?
0 votes
On ne peut pas l'utiliser et créer JsonResult ensuite, car le type de contenu ne peut pas être défini après l'envoi des en-têtes (parce que Flush les envoie).
0 votes
Parce qu'il n'y a pas une seule bonne réponse, je suppose :) J'ai créé une question qui m'était propre, mais je savais qu'elle serait aussi largement posée.
2 votes
La solution proposée ne fonctionne pas dans MVC 3.
1 votes
@Qua : La solution proposée date de plus de deux ans. Je ne m'attendrais pas non plus à ce qu'elle fonctionne pour MVC 3 ! En outre, il existe de meilleures façons de procéder aujourd'hui.
0 votes
@BishopBarber Merci. Corrigé !