Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render View programmatically into a string

I would like to get the html code a view would generate in a string, modify it in my controller, then add it to my JsonResult.

I found code that would do what i'm talking about from a partial. I would like to do it from an aspx View though.

-- Extra explanation:

Let's say I have a page Frame.aspx that /Controller/Frame will return

I would like to get my hand on the response before it out so I can to wrap it with jsonp. I do not wish to edit the return result in code every time, this is why I want to load the view programmatically.

/Controller/Frame currently returns Frame.aspx's content: <html><body>hello</body></html>

Let's say there's a function that renders a view in a string builder

StringBuilder sb = new StringBuilder();
RenderView(sb, "Frame");

now take sb and wrap it with jsonp:

public JsonResult Frame(string callback)
{
     StringBuilder sb = new StringBuilder();
     RenderView(sb, "Frame");

     return new JsonResult
     {
         Data = "(function() { " + callback + "(" +  clientResponse + "); })();"
         ,
         JsonRequestBehavior = JsonRequestBehavior.AllowGet
     };
}
like image 739
Abdo Avatar asked Jul 13 '10 03:07

Abdo


1 Answers

This works like a charm (got it through SO).

I use it like this:

public class OfferController : Controller
{
    [HttpPost]
    public JsonResult EditForm(int Id)
    {
        var model = Mapper.Map<Offer, OfferEditModel>(_repo.GetOffer(Id));

        return Json(new { status = "ok", partial = this.RenderPartialViewToString("Edit", model) });
    }
}



public static partial class ControllerExtensions
{
    public static string RenderPartialViewToString(this ControllerBase controller, string partialPath, object model)
    {
        if (string.IsNullOrEmpty(partialPath))
            partialPath = controller.ControllerContext.RouteData.GetRequiredString("action");

        controller.ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialPath);
            ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            // copy model state items to the html helper 
            foreach (var item in viewContext.Controller.ViewData.ModelState)
                if (!viewContext.ViewData.ModelState.Keys.Contains(item.Key))
                {
                    viewContext.ViewData.ModelState.Add(item);
                }


            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }
}
like image 188
John Landheer Avatar answered Oct 01 '22 18:10

John Landheer