web-dev-qa-db-fra.com

Dans MVC3 Razor, comment puis-je obtenir le html d'une vue rendue dans une action?

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

Est-ce quelque chose comme ça:

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

J'utilise une méthode statique dans une classe que j'ai appelée Utilities.Common Je reviens constamment au client en tant que propriétés des objets JSON, donc j'avais besoin de les rendre 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 ainsi que les vues partielles, il suffit de modifier ViewEngines.Engines.FindPartialView à ViewEngines.Engines.FindView.

152
Chev

La réponse acceptée par @Chev ci-dessus est bonne, mais je voulais rendre le résultat d'une action spécifique, et pas seulement d'une --- vue particulière.

De plus, je devais pouvoir transmettre des paramètres à cette action plutôt que de compter sur l'injection d'un modèle.

J'ai donc trouvé ma propre méthode, que j'ai mise dans la classe de base de mes contrôleurs (en la mettant à la disposition de 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 d'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 la ViewResult en invoquant la méthode Foo, puis appeler RenderViewResultAsString pour obtenir le texte HTML:

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

    var html = this.RenderViewResultAsString(viewResult);
4
Gary McGill