Je veux sortir deux vues différentes (une sous forme de chaîne qui sera envoyée par e-mail) et l'autre la page affichée à un utilisateur.
Est-ce possible dans ASP.NET MVC beta?
J'ai essayé plusieurs exemples:
1. RenderPartial to String dans ASP.NET MVC Beta
Si j'utilise cet exemple, je reçois le message "Impossible de rediriger après l'envoi des en-têtes HTTP".
2. Framework MVC: capture de la sortie d'une vue
Si j'utilise ceci, je semble être incapable de faire une redirectToAction, car il essaie de rendre une vue qui peut ne pas exister. Si je retourne la vue, elle est complètement foirée et ne semble pas du tout correcte.
Quelqu'un a-t-il des idées / solutions à ces problèmes ou ai-je des suggestions pour de meilleurs?
Merci beaucoup!
Voici un exemple. Ce que j'essaie de faire, c'est de créer la 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
En supposant un appel du contrôleur pour obtenir l'e-mail de confirmation de commande, en passant l'emplacement Site.Master.
string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);
la source
Réponses:
Voici ce que j'ai trouvé et ça marche pour moi. J'ai ajouté les méthodes suivantes à ma classe de base de contrôleur. (Vous pouvez toujours créer ces méthodes statiques ailleurs qui acceptent un contrôleur comme paramètre, je suppose)
Style MVC2 .ascx
Razor .cshtml style
Edit: ajout du code Razor.
la source
Cette réponse n'est pas sur mon chemin. C'est à l'origine de https://stackoverflow.com/a/2759898/2318354 mais ici j'ai montré comment l'utiliser avec le mot-clé "Static" pour le rendre commun à tous les contrôleurs.
Pour cela, vous devez créer une
static
classe dans un fichier de classe. (Supposons que votre nom de fichier de classe soit Utils.cs)Cet exemple est pour Razor.
Utils.cs
Vous pouvez maintenant appeler cette classe à partir de votre contrôleur en ajoutant NameSpace dans votre fichier contrôleur comme suit en passant "this" comme paramètre au contrôleur.
Comme suggéré par @Sergey, cette méthode d'extension peut également appeler depuis cotroller comme indiqué ci-dessous
J'espère que cela vous sera utile pour rendre le code propre et soigné.
la source
Cela fonctionne pour moi:
la source
J'ai trouvé une nouvelle solution qui rend une vue en chaîne sans avoir à jouer avec le flux de réponse du HttpContext actuel (qui ne vous permet pas de modifier le ContentType de la réponse ou d'autres en-têtes).
Fondamentalement, tout ce que vous faites est de créer un faux HttpContext pour que la vue se rende:
Cela fonctionne sur ASP.NET MVC 1.0, ainsi que ContentResult, JsonResult, etc. (la modification des en-têtes sur la HttpResponse d'origine ne renvoie pas l' exception «Le serveur ne peut pas définir le type de contenu après l'envoi des en-têtes HTTP »).
Mise à jour: dans ASP.NET MVC 2.0 RC, le code change un peu car nous devons passer le
StringWriter
utilisé pour écrire la vue dansViewContext
:la source
StringWriter
vous utilisez pour écrire dans leStringBuilder
, pas une nouvelle instance sinon la sortie de la vue sera perdue.Cet article décrit comment rendre une vue dans une chaîne dans différents scénarios:
La solution / le code est fourni sous la forme d'une classe appelée ViewRenderer . Il fait partie du WestwindToolkit de Rick Stahl sur GitHub .
Utilisation (3. - exemple WebAPI):
la source
Si vous voulez renoncer entièrement à MVC, évitant ainsi tout le désordre HttpContext ...
Cela utilise le moteur de rasoir open source génial ici: https://github.com/Antaris/RazorEngine
la source
CompilerErrors
propriété de l'exception.vous obtenez la vue en chaîne en utilisant cette façon
Nous appelons cette méthode de deux manières
OU
la source
Astuce supplémentaire pour ASP NET CORE:
Interface:
La mise en oeuvre:
Inscription dans
Startup.cs
Et l'utilisation dans le contrôleur:
la source
J'utilise MVC 1.0 RTM et aucune des solutions ci-dessus n'a fonctionné pour moi. Mais celui-ci a fait:
la source
J'ai vu une implémentation pour MVC 3 et Razor à partir d'un autre site Web, cela a fonctionné pour moi:
En savoir plus sur Razor render - MVC3 View Render to String
la source
Pour rendre une vue à une chaîne dans la couche de service sans avoir à passer ControllerContext, il y a un bon article de Rick Strahl ici http://www.codemag.com/Article/1312081 qui crée un contrôleur générique. Résumé du code ci-dessous:
Ensuite, pour rendre la vue dans la classe Service:
la source
Conseil rapide
Pour un modèle fortement typé, ajoutez-le simplement à la propriété ViewData.Model avant de passer à RenderViewToString. par exemple
la source
Pour répéter à partir d'une question plus inconnue, jetez un œil à MvcIntegrationTestFramework .
Cela vous permet d'économiser en écrivant vos propres assistants pour diffuser les résultats et il est prouvé que cela fonctionne assez bien. Je suppose que ce serait dans un projet de test et en bonus, vous auriez les autres capacités de test une fois que vous aurez cette configuration. Le problème principal serait probablement de trier la chaîne de dépendance.
la source
Voici une classe que j'ai écrite pour le faire pour ASP.NETCore RC2. Je l'utilise pour pouvoir générer des e-mails html à l'aide de Razor.
la source
J'ai trouvé un meilleur moyen de rendre la page de vue du rasoir lorsque j'ai eu une erreur avec les méthodes ci-dessus, cette solution pour l'environnement de formulaire Web et l'environnement mvc. Aucun contrôleur n'est nécessaire.
Voici l'exemple de code, dans cet exemple, j'ai simulé une action mvc avec un gestionnaire http asynchrone:
la source