简体   繁体   English

将视图呈现为字符串时,ASP.NET MVC无法呈现自定义显示模板

[英]ASP.NET MVC not rendering custom display templates when rendering view as a string

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. 我需要在我的应用程序中呈现一个特定的MVC视图(用于数百个数据库记录-每个记录呈现一个视图),每个视图均以字符串形式呈现,以便将它们保存到* .html文件中以供离线查看。

I have found several sources on how to do this: 我发现了一些有关如何执行此操作的资源:

How to render an ASP.NET MVC ViewResult to HTML? 如何将ASP.NET MVC ViewResult呈现为HTML?

and

http://www.west-wind.com/weblog/posts/2012/May/30/Rendering-ASPNET-MVC-Views-to-String 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. 我的问题是我的视图调用了Html.DisplayFor(它渲染了我的自定义显示模板),而这些模板也调用了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. 当我使用上面链接中的方法时,似乎正在使用默认的显示模板,并且未为视图的那些区域呈现MY HTML。

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. 请注意,当我让MVC将其呈现为ViewResult并在屏幕上显示它们时,我尝试呈现为字符串的视图使用自定义显示模板就可以很好地呈现。

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? 有什么方法可以将MVC视图呈现为字符串,以便可以将其保存到使用自定义显示模板而不是默认显示模板的文件中? 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: 示例ViewModel和一些包含的类:

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

Were I you, I'd take this from a different approach. 如果我是您,我会从另一种角度考虑。 Do Child Action Method Output Caching and then create a custom cache provider that saves to and reads from disk. 执行“子操作方法输出缓存”,然后创建一个自定义缓存提供程序,该提供程序保存到磁盘并从磁盘读取数据。 This way you'd take the rendered output and store it to disk. 这样,您将获取渲染的输出并将其存储到磁盘。 I have a blog entry that walks you through it. 我有一个博客条目,引导您完成整个过程。

http://www.haneycodes.net/custom-output-caching-with-mvc3-and-net-4-0-done-right http://www.haneycodes.net/custom-output-caching-with-mvc3-and-net-4-0-done-right

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM