I need to render a specific MVC view in my app (for a couple hundred database records - one view rendered per record) each as a string so that I can save them out to *.html files for offline viewing.
I have found several sources on how to do this:
How to render an ASP.NET MVC ViewResult to HTML?
and
http://www.west-wind.com/weblog/posts/2012/May/30/Rendering-ASPNET-MVC-Views-to-String
which seem to work fine with just basic views. My problem is that my view makes calls to Html.DisplayFor (which renders my custom display templates), and those templates also make calls to Html.DisplayFor. When I am using the methods in the links above, it seems as a default display template is being used and none of MY HTML is being rendered for those areas of my views.
Note that the views that I am attempting to render as string render just fine with the custom display templates when letting MVC render them out to a ViewResult and displaying them on screen.
Is there any way to render an MVC view as a string so that it can be saved out to file where the custom display templates are used instead of the default? I would prefer not to have to create a new view specifically for this purpose that contains no custom display templates. Any help is greatly appreciated.
Here is an example of my code stripped to just show the most basic functionality. Again, this works fine for basic views, just not with my custom display templates.
public void GenerateOfflinePackage(IndexViewModel model, ControllerContext controllerContext)
{
var folderName = Guid.NewGuid().ToString();
var tempPackagePath = string.Format("{0}\\{1}", this.hostingEnvironmentWrapper.MapPath("~/App_Data"), folderName);
Directory.CreateDirectory(tempPackagePath);
var cpfModel = this.careerPlanningFormService.BuildSummaryViewModel(59);
var viewString = this.RenderRazorViewToString("~/Views/CPF/Summary.cshtml", cpfModel, controllerContext);
using (StreamWriter outfile = new StreamWriter(tempPackagePath + @"\59.html", true))
{
outfile.Write(viewString);
}
}
public string RenderRazorViewToString(string viewName, object model, ControllerContext ctxt)
{
var s = string.Empty;
var viewData = ctxt.Controller.ViewData;
var tempData = ctxt.Controller.TempData;
viewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ctxt, viewName);
var viewContext = new ViewContext(ctxt, viewResult.View, viewData, tempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ctxt, viewResult.View);
s = sw.GetStringBuilder().ToString();
}
return s;
}
Example ViewModel and some included classes:
public class SummaryViewModel : CareerPlanningFormBase
{
public string StaffName { get; set; }
public string StaffImageUrl { get; set; }
public string PredominantRole { get; set; }
public IList<SummaryResultsMeasuresSectionModel> ResultsMeasuresSections { get; set; }
}
public class SummaryResultsMeasuresSectionModel
{
public string SectionName { get; set; }
public string SectionLabelTitle { get; set; }
public string SectionLabelText { get; set; }
public IList<SummaryResultsMeasureModel> ResultsMeasures { get; set; }
}
public class SummaryResultsMeasureModel
{
public string ResultsMeasureName { get; set; }
public IEnumerable<string> MeasureTypes { get; set; }
public IList<SummaryResultsMeasureCriterionModel> ResultsMeasureCriteria { get; set; }
public IEnumerable<SummaryActionPlanModel> ActionPlans { get; set; }
}