web-dev-qa-db-ja.com

MVC3 Razorでは、アクション内でレンダリングされたビューのhtmlを取得するにはどうすればよいですか?

アクション内でビューの生成されたhtmlを取得する方法を知っている人はいますか?

次のようなものですか:

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

Utilities.Commonというクラスで静的メソッドを使用します。ビューをクライアントにJSONオブジェクトのプロパティとして常に渡しているため、ビューを文字列にレンダリングする必要がありました。ここに行く:

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();
    }
}

これは、部分ビューだけでなく完全ビューでも機能します。ViewEngines.Engines.FindPartialViewViewEngines.Engines.FindViewに変更するだけです。

152
Chev

上記の@Chevによる受け入れられた答えは良いですが、特定のviewではなく、特定のactionの結果をレンダリングしたかったのです。

また、モデルの注入に依存するのではなく、そのアクションにパラメーターを渡すことができる必要がありました。

そこで、私は自分のメソッドを思いつき、それをコントローラーの基本クラスに入れました(すべてのコントローラーが使用できるようにします)。

    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);
        }
    }

モデルオブジェクトと他のパラメーターを使用するFooというアクションがあり、これらが一緒に使用されるビューに影響するとします。

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

ここで、アクションFooを呼び出した結果を取得したい場合、ViewResultメソッドを呼び出してFooを取得し、RenderViewResultAsStringを呼び出すだけで済みます。 HTMLテキストを取得するには:

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

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