RazorEngine不能使用@Html.Raw引起的连锁反应以及解决办法


C#使用RazorEngine解析模板

.NETCore动态解析Razor代码cshtml代码解析RazorEngine.NetCore - 文章随笔 - YES开发框架网 (yesdotnet.com)

遇到问题

一、不支持@Html.Raw写法

https://github.com/Antaris/RazorEngine/issues/533

解决方案:

使用Raw代替即可

RazorEngine不能使用@Html.Raw引起的连锁反应以及解决办法

二、使用Raw,VS中调试代码无法运行时修改代码

因为@Raw不能被VS识别,所以,如果虽然编译我们排除了自己的cshtml不让VS编译,但是运行调试的时候,VS还是会尝试去编译我们自己的模板CShtml,然后就会爆出错误咯,又因为存在错误,所以VS就提示无法编译编辑了,每次修改又要痛苦的停止,修改,编译运行,怎么能够忍受

RazorEngine不能使用@Html.Raw引起的连锁反应以及解决办法

解决思路,就是让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开发框架网发布内容,转载请附上原文出处连接
管理员
上一篇:AS.NET Core自定义类中全局访问HttpContext
下一篇:CodeMirror配合js-beautify格式化代码后,光标恢复到原来位置
评论列表

发表评论

评论内容
昵称:
关联文章

RazorEngine使用@Html.Raw引起连锁反应以及解决办法
formsubmit()方法触发onsubmit事件解决方法,兼容各版本浏览器。
关于RazorEngine研究过程中记录
winform应用退出彻底解决办法
Node.js版本引起 构建失败提示throw new ERR_INVALID_CALLBACK();
.NET Core 项目调试时候修改代码
HTML IMG 图片链接404错误,引起alt超长影响界面美观
当CDN服务可用时,前端有什么解决办法
浏览器限制最小字体为12号解决办法
VSCode无法格式化python代码py文件解决办法
ASP.NET+MVC入门踩坑笔记 (一) 创建项目 项目配置运行 以及简单Api搭建
表结构修改>新增主键或者为空
element-ui el-table显示合计行解决办法
使用.NET 6开发TodoList应用(10)——实现DELETE请求以及HTTP请求幂等性
.NETCore动态解析Razor代码cshtml代码解析RazorEngine.NetCore
Python退出主进程后子线程会退出解决方案
.net HTML解析工具HtmlAgilityPack使用
YESWEB POS开发 Electron运行生成报错解决办法
【gitblit复制URL】 修改URL复制方式Flash插件被浏览器禁用解决办法
Elastic AMP监控.NET程序性

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码