RazorEngine不能使用@Html.Raw引起的连锁反应以及解决办法
C#使用RazorEngine解析模板
.NETCore动态解析Razor代码cshtml代码解析RazorEngine.NetCore - 文章随笔 - YES开发框架网 (yesdotnet.com)
遇到问题
一、不支持@Html.Raw写法
https://github.com/Antaris/RazorEngine/issues/533
解决方案:
使用Raw代替即可
二、使用Raw,VS中调试代码无法运行时修改代码
因为@Raw不能被VS识别,所以,如果虽然编译我们排除了自己的cshtml不让VS编译,但是运行调试的时候,VS还是会尝试去编译我们自己的模板CShtml,然后就会爆出错误咯,又因为存在错误,所以VS就提示无法编译编辑了,每次修改又要痛苦的停止,修改,编译运行,怎么能够忍受
解决思路,就是让RazorEngine支持@Html.Raw的写法,这样VS就不会报错,应该就能断点修改代码了
让RazorEngine支持@Html.Raw
正确的解决方案
与MVC的Razor View引擎一样,RazorEngine会自动编码写入模板的值。 为了解决这个问题,我们引入了一个名为Raw的接口,默认实现为TemplateBase和RawString。
要使用后者,只需调用TemplateBase的内置Raw方法,因此我们要想办法把TemplateBase.Raw暴漏为Html.Raw的方式
RazorHelper.cs代码
C# 全选
using RazorEngine;
using RazorEngine.Configuration;
using RazorEngine.Templating;
using RazorEngine.Text;
using System;
namespace YESCMS.Libs
{
public class RazorHelper
{
//static InvalidatingCachingProvider cacheProvidxer { get; set; }
//static TemplateServiceConfiguration Configuration { get; set; }
static RazorHelper()
{
var Configuration = new TemplateServiceConfiguration()
{
BaseTemplateType = typeof(HtmlTemplateBase<>)
//TemplateManager = new MyTemplateManager()
};
Engine.Razor = RazorEngineService.Create(Configuration);
//cacheProvidxer = new InvalidatingCachingProvider();
//var config = new TemplateServiceConfiguration();
//config.CachingProvider = cacheProvidxer;
//var service = RazorEngineService.Create(config);
//Engine.Razor = service;
}
public static void Init()
{
TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration();
templateConfig.Namespaces.Add("my namespace");
//IRazorEngineService
var service = RazorEngineService.Create();
Engine.Razor = service;
}
public static void ResetCache()
{
//Configuration.CachingProvider.Dispose();
//Configuration.CachingProvider = new RazorEngine.Templating.DefaultCachingProvider();
//cacheProvidxer.InvalidateAll();
}
public static string RenderRazorSource(string templateSource, string name, DynamicViewBag viewBag)
{
try
{
if (Engine.Razor.IsTemplateCached(name, null))
{
var result = Engine.Razor.Run(name, viewBag: viewBag);
return result;
}
else
{
//DynamicViewBag viewBag = new DynamicViewBag();
var result = Engine.Razor.RunCompile(templateSource, name, viewBag: viewBag);
return result;
}
}
catch (Exception ex)
{
return ex.GetExceptionMsg();
}
}
public static string RenderRazorFile(string fileName, string name, Type modelType = null, object model = null, DynamicViewBag viewBag = null)
{
try
{
string templateSource = System.IO.File.ReadAllText(fileName, System.Text.Encoding.UTF8);
var fi = new System.IO.FileInfo(fileName);
string templateKey = name + new DateTimeOffset(fi.LastWriteTime).ToUnixTimeSeconds();
if (Engine.Razor.IsTemplateCached(templateKey, null))
{
var result = Engine.Razor.Run(templateKey, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
else
{
//DynamicViewBag viewBag = new DynamicViewBag();
var result = Engine.Razor.RunCompile(templateSource, templateKey, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
}
catch (Exception ex)
{
return ex.GetExceptionMsg();
}
}
static string RenderRazor(string template, string name, Type modelType = null, object model = null, DynamicViewBag viewBag = null)
{
try
{
if (Engine.Razor.IsTemplateCached(name, modelType))
{
var result = Engine.Razor.Run(name, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
else
{
//DynamicViewBag viewBag = new DynamicViewBag();
//Engine.Razor.CompileRunner()
var result = Engine.Razor.RunCompile(template, name, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
}
catch (Exception ex)
{
return ex.GetExceptionMsg();
}
}
public class MyTemplateManager : RazorEngine.Templating.DelegateTemplateManager
{
}
}
public class HtmlTemplateBase<T> : TemplateBase<T>
{
// 正确的方案,TemplateBase.Raw通过Html.Raw的方式暴漏给cshtml
private RazorHtml<T> _html = null;
public RazorHtml<T> Html
{
get
{
if (_html == null)
{
_html = new RazorHtml<T>(this);
}
return _html;
}
}
}
public class RazorHtml<T>
{
TemplateBase<T> c;
public RazorHtml(TemplateBase<T> context)
{
this.c = context;
}
public IEncodedString Raw(string rawString)
{
return this.c.Raw(rawString);
}
}
}
使用例子:
C# 全选
static void WriteDiskCache(DiskWriteArticleData data, string templateFile)
{
// 模板名称
string templateName = "view_" + data.Category;
// 模板编译
string html = RazorHelper.RenderRazorFile(templateFile,templateName , typeof(DiskWriteArticleData), data);
// 要保存的文件名
string fileName = System.IO.Path.Combine(PathProvider.GetRootArticleView(), data.Category, data.ArticleID + ".html");
WriteHtmlToFile(html, fileName);
}
其他记录
重构Engine.Razor模板
C# 全选
var Configuration = new TemplateServiceConfiguration()
{
BaseTemplateType = typeof(HtmlTemplateBase<>)
//TemplateManager = new MyTemplateManager()
};
Engine.Razor = RazorEngineService.Create(Configuration);
C# 全选
public class HtmlTemplateBase<T> : TemplateBase<T>
{
private IHtmlHelper helper = null;
public IHtmlHelper Html
{
get
{
if (helper == null)
{
var httpcontext = MvcContext.GetContext();
helper = httpcontext.RequestServices.GetRequiredService<IHtmlHelperFactory>().Create();
}
return helper;
}
}
}
MvcContext.cs
参考:
AS.NET Core自定义类中全局访问HttpContext - 文章随笔 - YES开发框架网 (yesdotnet.com)
HtmlHelperFactory
C# 全选
public interface IHtmlHelperFactory
{
IHtmlHelper Create();
}
public class HtmlHelperFactory : IHtmlHelperFactory
{
private readonly IHttpContextAccessor _contextAccessor;
public class FakeView : IView
{
/// <inheritdoc />
public Task RenderAsync(ViewContext context)
{
return Task.CompletedTask;
}
/// <inheritdoc />
public string Path { get; } = "View";
}
public HtmlHelperFactory(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
/// <inheritdoc />
public IHtmlHelper Create()
{
var modelMetadataProvider = _contextAccessor.HttpContext.RequestServices.GetRequiredService<IModelMetadataProvider>();
var tempDataProvider = _contextAccessor.HttpContext.RequestServices.GetRequiredService<ITempDataProvider>();
var htmlHelper = _contextAccessor.HttpContext.RequestServices.GetRequiredService<IHtmlHelper>();
var viewContext = new ViewContext(
new ActionContext(_contextAccessor.HttpContext, _contextAccessor.HttpContext.GetRouteData(), new ControllerActionDescriptor()),
new FakeView(),
new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary()),
new TempDataDictionary(_contextAccessor.HttpContext, tempDataProvider),
TextWriter.Null,
new HtmlHelperOptions()
);
((IViewContextAware)htmlHelper).Contextualize(viewContext);
return htmlHelper;
}
}
startup.cs配置
C# 全选
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IHtmlHelperFactory, HtmlHelperFactory>();
}
配置完成后,就能在自己的cshtml模板中 使用@Html.Raw
了
RazorHelper.cs
C# 全选
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using RazorEngine;
using RazorEngine.Configuration;
using RazorEngine.Templating;
using System;
using System.IO;
using System.Threading.Tasks;
namespace YESCMS.Libs
{
public class HtmlTemplateBase<T> : TemplateBase<T>
{
private IHtmlHelper helper = null;
public IHtmlHelper Html
{
get
{
if (helper == null)
{
var httpcontext = MvcContext.GetContext();
helper = httpcontext.RequestServices.GetRequiredService<IHtmlHelperFactory>().Create();
}
return helper;
}
}
}
public class MvcContext
{
public static IHttpContextAccessor Accessor;
public static HttpContext GetContext()
{
return Accessor.HttpContext;
}
}
public class RazorHelper
{
//static InvalidatingCachingProvider cacheProvidxer { get; set; }
//static TemplateServiceConfiguration Configuration { get; set; }
static RazorHelper()
{
var Configuration = new TemplateServiceConfiguration()
{
BaseTemplateType = typeof(HtmlTemplateBase<>)
//TemplateManager = new MyTemplateManager()
};
Engine.Razor = RazorEngineService.Create(Configuration);
//cacheProvidxer = new InvalidatingCachingProvider();
//var config = new TemplateServiceConfiguration();
//config.CachingProvider = cacheProvidxer;
//var service = RazorEngineService.Create(config);
//Engine.Razor = service;
}
public static void Init()
{
TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration();
templateConfig.Namespaces.Add("my namespace");
//IRazorEngineService
var service = RazorEngineService.Create();
Engine.Razor = service;
}
public static void ResetCache()
{
//Configuration.CachingProvider.Dispose();
//Configuration.CachingProvider = new RazorEngine.Templating.DefaultCachingProvider();
//cacheProvidxer.InvalidateAll();
}
public static string RenderRazorSource(string templateSource, string name, DynamicViewBag viewBag)
{
try
{
if (Engine.Razor.IsTemplateCached(name, null))
{
var result = Engine.Razor.Run(name, viewBag: viewBag);
return result;
}
else
{
//DynamicViewBag viewBag = new DynamicViewBag();
var result = Engine.Razor.RunCompile(templateSource, name, viewBag: viewBag);
return result;
}
}
catch (Exception ex)
{
return ex.GetExceptionMsg();
}
}
public static string RenderRazorFile(string fileName, string name, Type modelType = null, object model = null, DynamicViewBag viewBag = null)
{
try
{
string templateSource = System.IO.File.ReadAllText(fileName, System.Text.Encoding.UTF8);
var fi = new System.IO.FileInfo(fileName);
string templateKey = name + new DateTimeOffset(fi.LastWriteTime).ToUnixTimeSeconds();
if (Engine.Razor.IsTemplateCached(templateKey, null))
{
var result = Engine.Razor.Run(templateKey, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
else
{
//DynamicViewBag viewBag = new DynamicViewBag();
var result = Engine.Razor.RunCompile(templateSource, templateKey, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
}
catch (Exception ex)
{
return ex.GetExceptionMsg();
}
}
static string RenderRazor(string template, string name, Type modelType = null, object model = null, DynamicViewBag viewBag = null)
{
try
{
if (Engine.Razor.IsTemplateCached(name, modelType))
{
var result = Engine.Razor.Run(name, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
else
{
//DynamicViewBag viewBag = new DynamicViewBag();
//Engine.Razor.CompileRunner()
var result = Engine.Razor.RunCompile(template, name, modelType: modelType, model: model, viewBag: viewBag);
return result;
}
}
catch (Exception ex)
{
return ex.GetExceptionMsg();
}
}
public class MyTemplateManager : RazorEngine.Templating.DelegateTemplateManager
{
}
}
public interface IHtmlHelperFactory
{
IHtmlHelper Create();
}
public class HtmlHelperFactory : IHtmlHelperFactory
{
private readonly IHttpContextAccessor _contextAccessor;
public class FakeView : IView
{
/// <inheritdoc />
public Task RenderAsync(ViewContext context)
{
return Task.CompletedTask;
}
/// <inheritdoc />
public string Path { get; } = "View";
}
public HtmlHelperFactory(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
/// <inheritdoc />
public IHtmlHelper Create()
{
var modelMetadataProvider = _contextAccessor.HttpContext.RequestServices.GetRequiredService<IModelMetadataProvider>();
var tempDataProvider = _contextAccessor.HttpContext.RequestServices.GetRequiredService<ITempDataProvider>();
var htmlHelper = _contextAccessor.HttpContext.RequestServices.GetRequiredService<IHtmlHelper>();
var viewContext = new ViewContext(
new ActionContext(_contextAccessor.HttpContext, _contextAccessor.HttpContext.GetRouteData(), new ControllerActionDescriptor()),
new FakeView(),
new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary()),
new TempDataDictionary(_contextAccessor.HttpContext, tempDataProvider),
TextWriter.Null,
new HtmlHelperOptions()
);
((IViewContextAware)htmlHelper).Contextualize(viewContext);
return htmlHelper;
}
}
}
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
post 管理员