-1

So this might sound a bit odd, but essentially I'm trying to render a view ahead of time in a controller so I can pass it to a property in a model. (This is so I can later pass the view's rendered HTML to a service call, so I have a reason.) I have code that almost accomplishes this (adapted from this answer), with the bad side effect of returning a view that's been rendered twice:

public ActionResult Action(object paramater)
{
   var model = new MyModel(parameter);
   ViewResult view = View("~/... path to view .../View.cshtml", model);

   string data;

   using (var sw = new StringWriter())
   {
      view.ExecuteResult(ControllerContext);
      var viewContext = new ViewContext(ControllerContext, view.View, ViewData, TempData, sw);
      view.View.Render(viewContext, sw);
      data = sw.ToString();
   }

   model.ViewRender = data;

   return view;
}

This successfully puts a copy of the view's HTML in the model, but the view itself is rendered twice (so it seems), so I get a webpage back that is two copies of the same thing, one on top of the other.

I've tried a couple different ways of returning the view without this side effect—making a new one entirely with return View(model), going into another method—nothing has worked so far.

Community
  • 1
  • 1
Andrew
  • 4,953
  • 15
  • 40
  • 58

2 Answers2

1

Instead of returning the view, you should return the raw content:

return Content(data, "text/html");
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Doesn't work. I still get a duplicated view, and on top of that this doesn't pass my model around. – Andrew Dec 20 '11 at 14:45
  • Doesn't pass your model to what? Try returning `null` or `void`. – SLaks Dec 20 '11 at 14:56
  • The whole reason I want the rendered view is to pass it into the model. Using `return Content` doesn't use the data I rendered and defeats the whole purpose of this question. – Andrew Dec 20 '11 at 14:57
  • If the view is already rendered in the model, why do you need to render it again? (or am I misunderstanding?) – SLaks Dec 20 '11 at 14:59
  • I want to (1) put the view in the browser, like you'd normally do, and (2) be able to retrieve the rendered HTML to use later, like I said in the question. – Andrew Dec 20 '11 at 15:01
  • But why can't you just return the stored HTML? Why do you need to render twice? – SLaks Dec 20 '11 at 15:11
  • So far this is the best method I've been able to come up with to get MVC to give my controllers rendered HTML from a page. I want to display the HTML to the user but also use it in the controller. – Andrew Dec 20 '11 at 15:13
0

I figured it out. view.ExecuteResult() writes directly to HttpContext.Response, so a call to HttpResponse.Clear() before returning a new view worked perfectly:

public ActionResult Action(object paramater)
{
   var model = new MyModel(parameter);
   ViewResult view = View("~/... path to view .../View.cshtml", model);

   string data;

   using (var sw = new StringWriter())
   {
      view.ExecuteResult(ControllerContext);
      var viewContext = new ViewContext(ControllerContext, view.View, ViewData, TempData, sw);
      view.View.Render(viewContext, sw);
      data = sw.ToString();
   }

   model.ViewRender = data;
   HttpContext.Response.Clear();

   return View("~/... path to view .../View.cshtml", model);
}
Andrew
  • 4,953
  • 15
  • 40
  • 58