简体   繁体   English

C#渲染无控制器的局部视图

[英]C# Render Partial View Without Controller

I am having trouble using "RenderPartialViewToString" without a controller class. 我在使用没有控制器类的“RenderPartialViewToString”时遇到问题。

I am currently having to create HTML within application start up which requires making a model, making a view and turning the view in to a HTML string. 我目前不得不在应用程序启动时创建HTML,这需要制作模型,制作视图并将视图转换为HTML字符串。

Within my view it uses HTML Helper function/extension which seems to only be there if a controller is there. 在我的视图中,它使用HTML Helper函数/扩展,如果有控制器,它似乎只存在。

Can anyone shed some light on how I can do this? 任何人都可以阐明我如何做到这一点?

You couldn't use html helper without current controller context.Try this extensions for render view into html 如果没有当前控制器上下文,则无法使用html帮助程序。请将此扩展名用于渲染视图到html

public static class RenderViewHelper
{
    public static string RenderPartialToString(string viewPath, object model)
    {
        string viewAbsolutePath = MapPath(viewPath);

        var viewSource = File.ReadAllText(viewAbsolutePath);

        string renderedText = Razor.Parse(viewSource, model);
        return renderedText;
    }

    public static string RenderPartialToString(ControllerContext context, string partialViewName, object model)
    {
        ViewEngineResult result = ViewEngines.Engines.FindPartialView(context, partialViewName);

        var viewData = new ViewDataDictionary() { Model = model };

        if (result.View != null)
        {
            var sb = new StringBuilder();

            using (var sw = new StringWriter(sb))
            {
                using (var output = new HtmlTextWriter(sw))
                {
                    var viewContext = new ViewContext(context, result.View, viewData, new TempDataDictionary(), output);
                    result.View.Render(viewContext, output);
                }
            }

            return sb.ToString();
        }

        return string.Empty;
    }

    public static string MapPath(string filePath)
    {
        return HttpContext.Current != null ? HttpContext.Current.Server.MapPath(filePath) : string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, filePath.Replace("~", string.Empty).TrimStart('/'));
    }
}

First method used razor engine library. 第一种方法是使用razor引擎库。 Second work with controller context. 第二次使用控制器上下文。

Razor.Parse is deprecated now. Razor.Parse现已弃用。 With version 3.5 of the Razor engine you would follow the steps outlined here: https://antaris.github.io/RazorEngine/Upgrading.html 使用Razor引擎版本3.5,您将按照此处列出的步骤操作: https//antaris.github.io/RazorEngine/Upgrading.html

The text below is copied verbatim from the above link: 以下文字从上述链接逐字复制:

var result = Razor.Parse(razorTemplate, model, cache_name)

is now either (when the modeltype is known or you want to precompile on startup) 现在要么(当模型类型已知或您想要在启动时预编译)

// Once at startup (not required when using an ITemplateManager which knows how to resolve cache_name)
Engine.Razor.AddTemplate(cache_name, razorTemplate)
// On startup
Engine.Razor.Compile(cache_name, typeof(MyModel) /* or model.GetType() or null for 'dynamic'*/)

// instead of the Razor.Parse call
var result = Engine.Razor.Run(cache_name, typeof(MyModel) /* or model.GetType() or null for 'dynamic'*/, model)

or (when you want lazy compilation, like Parse) 或者(当你想要懒惰的编译时,比如Parse)

// Once at startup (not required when using an ITemplateManager which knows how to resolve cache_name)
Engine.Razor.AddTemplate(cache_name, razorTemplate)

// instead of the Razor.Parse call
var result = Engine.Razor.RunCompile(cache_name, typeof(MyModel) /* or model.GetType() or null for 'dynamic'*/, model)

The semantic equivalent one-liner would be (only to be used to get started with RazorEngine quickly): 语义等效单行将是(仅用于快速开始使用RazorEngine):

// This will just call AddTemplate for you (every time), note that the ITemplateManager has to support AddTemplate
// and it has to handle multiple calls to AddTemplate gracefully to make this work.
// The default implementation will throw an exception when you use the same cache_name for different templates.
var result = Engine.Razor.RunCompile(razorTemplate, cache_name, model.GetType() /* typeof(MyModel) or or null for 'dynamic'*/, model

A very nice answer to this question is Westwind.Web.Mvc.ViewRenderer . 对这个问题的一个非常好的答案是Westwind.Web.Mvc.ViewRenderer

Explain: If you want to render views outside MVC you need ControllerContext that is fully functional and Razor can get all information from it. 说明:如果要在MVC之外渲染视图,则需要完全正常运行的ControllerContext,Razor可以从中获取所有信息。

By using the ViewRenderer class you just can call this method to render view by passing model and view data dictionary: 通过使用ViewRenderer类,您可以通过传递模型和视图数据字典来调用此方法来呈现视图:

    public class EmptyController : Controller { }

    public static string RenderRazorViewToString(string viewName, [Optional] object model,[Optional] ViewDataDictionary viewData)
    {
        var controller = ViewRenderer.CreateController<EmptyController>();
        controller.ViewData =viewData??new ViewDataDictionary();
        controller.ViewData.Model = model;
        var context = controller.ControllerContext;
        var html = ViewRenderer.RenderView(viewName, model, context);
        return html;
    }

I hope this would helpful. 我希望这会有所帮助。

Enjoy :) 请享用 :)

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

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