C#渲染不带控制器的局部视图
我在没有控制器类的情况下使用“RenderPartialViewToString”时遇到问题 我目前必须在应用程序启动中创建HTML,这需要创建一个模型,创建一个视图,并将视图转换为HTML字符串 在我的视图中,它使用HTML帮助函数/扩展,似乎只有在控制器存在时才存在C#渲染不带控制器的局部视图,c#,asp.net-mvc,renderpartial,C#,Asp.net Mvc,Renderpartial,我在没有控制器类的情况下使用“RenderPartialViewToString”时遇到问题 我目前必须在应用程序启动中创建HTML,这需要创建一个模型,创建一个视图,并将视图转换为HTML字符串 在我的视图中,它使用HTML帮助函数/扩展,似乎只有在控制器存在时才存在 有人能告诉我如何做到这一点吗?如果没有当前控制器上下文,您无法使用html帮助程序。请尝试将视图渲染为html的扩展 public static class RenderViewHelper { public stati
有人能告诉我如何做到这一点吗?如果没有当前控制器上下文,您无法使用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('/'));
}
}
第一种方法使用razor引擎库。第二项工作是使用控制器上下文。Razor.Parse现在不推荐使用。对于Razor引擎的3.5版,您将遵循此处概述的步骤: 以下文本是从上述链接逐字复制的:
var result = Razor.Parse(razorTemplate, model, cache_name)
现在是(当模型类型已知或您希望在启动时预编译时)
或者(当您需要延迟编译时,如解析)
语义等价的一行代码是(仅用于快速入门RazorEngine):
这个问题的一个很好的答案是 说明: 如果要在MVC之外渲染视图,则需要功能齐全的ControllerContext,Razor可以从中获取所有信息 通过使用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;
}
public类EmptyController:Controller{}
公共静态字符串RenderRazorViewToString(字符串视图名称,[可选]对象模型,[可选]ViewDataDictionary viewData)
{
var controller=ViewRenderer.CreateController();
controller.ViewData=ViewData??新建ViewDataDictionary();
controller.ViewData.Model=模型;
var context=controller.ControllerContext;
var html=ViewRenderer.RenderView(视图名称、模型、上下文);
返回html;
}
我希望这会有帮助
享受:)无法在“Razor.Parse”处重新插入符号“Razor”下载Razor引擎库。从Nuget
安装软件包RazorEngine
或访问其页面的EmptyController包含在ViewRenderer.cs源文件中。可以删除。您需要HttpContext.Current
才能为ViewRenderer提供完整的功能值。只要控制器在web服务器中运行时使用它,就可以了。对于单元测试(没有web服务器和HttpContext.Current==null),我试图解决它,但总是在MVC代码的深处出现相同的NullReferenceException,没有进一步的信息。相反,我最终使用了RazorEngine,因为它在有HttpContext和没有HttpContext的两种情况下都能工作。@Manfred,谢谢。我对null HttpContext也有同样的问题。你有RazorEngine的工作示例链接吗?不幸的是,我没有可以共享的工作示例。总的来说,RazorEngine相当直截了当且易于使用,尽管.RazorEngine目前没有在.NET Core 2.0上运行;RazorLight不适用于HTML帮助程序或标记帮助程序,并且ControllerContext不可实现,因此如果需要安排任务,它将不起作用。因此,到目前为止,似乎还没有一个真正好的解决方案。
// 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)
// 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
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;
}