90 votes

Dans MVC3 Razor, comment puis-je obtenir le html d'une vue rendue à l'intérieur d'une action ?

Quelqu'un sait-il comment obtenir le html généré d'une vue dans une action ?

Est-ce que c'est quelque chose comme ça :

public ActionResult Do()
{
    var html = RenderView("hello", model);
...
}

152voto

Alex Ford Points 15277

J'utilise une méthode statique dans une classe appelée Utilities.Common Je renvoie constamment les vues au client en tant que propriétés d'objets JSON. J'avais donc besoin de les convertir en chaîne. Et voilà :

public static string RenderPartialViewToString(Controller controller, string viewName, object model)
{
    controller.ViewData.Model = model;
    using (StringWriter sw = new StringWriter())
    {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
        ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.ToString();
    }
}

Cela fonctionnera pour les vues complètes comme pour les vues partielles, il suffit de modifier ViewEngines.Engines.FindPartialView a ViewEngines.Engines.FindView .

4voto

Gary McGill Points 8009

La réponse acceptée par @Chev ci-dessus est bonne, mais je voulais rendre le résultat d'une opération spécifique action et pas seulement un voir .

De plus, j'avais besoin de pouvoir passer des paramètres à cette action plutôt que de m'appuyer sur l'injection d'un modèle.

J'ai donc créé ma propre méthode, que j'ai placée dans la classe de base de mes contrôleurs (ce qui la rend disponible pour tous) :

    protected string RenderViewResultAsString(ViewResult viewResult)
    {
        using (var stringWriter = new StringWriter())
        {
            this.RenderViewResult(viewResult, stringWriter);

            return stringWriter.ToString();
        }
    }

    protected void RenderViewResult(ViewResult viewResult, TextWriter textWriter)
    {
        var viewEngineResult = this.ViewEngineCollection.FindView(
            this.ControllerContext, 
            viewResult.ViewName, 
            viewResult.MasterName);
        var view = viewEngineResult.View;

        try
        {
            var viewContext = new ViewContext(
                this.ControllerContext, 
                view, 
                this.ViewData, 
                this.TempData, 
                textWriter);

            view.Render(viewContext, textWriter);
        }
        finally
        {
            viewEngineResult.ViewEngine.ReleaseView(this.ControllerContext, view);
        }
    }

Supposons que j'ai une action appelée Foo qui prend un objet modèle et quelques autres paramètres, qui ensemble influencent la vue qui sera utilisée :

    public ViewResult Foo(MyModel model, int bar)
    {
        if (bar == 1)
            return this.View("Bar1");
        else
            return this.View("Bar2", model);
    }

Maintenant, si je veux obtenir le résultat de l'appel de l'action Foo je peux simplement obtenir le ViewResult en invoquant le Foo et ensuite appeler RenderViewResultAsString pour obtenir le texte HTML :

    var viewResult = this.Foo(model, bar);

    var html = this.RenderViewResultAsString(viewResult);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X