首页 新闻 会员 周边 捐助

ASP.NET Core 中如何将 .cshtml 视图文件生成为 .cs 文件

0
悬赏园豆:50 [待解决问题]

就像 DeveloperExceptionPage 中的 ErrorPage.cshtml 生成了一个 ErrorPage.Designer.cs ,请问如何可以实现?

问题补充:

用的是 ASP.NET Core 3.0

经过折腾终于通过下面的代码将 .cshtml 生成了 .cs ,但生成的 .cs 文件无法正常使用

class Program
{
    static void Main(string[] args)
    {
        var dir = new DirectoryInfo("../Cnblogs.Web.ErrorPages/Views/Errors/");
        foreach (var file in dir.GetFiles("*.cshtml"))
        {
            RazorToCSharp(file.Name);
        }
    }

    private static void  RazorToCSharp(string filename)
    {
        var baseType = filename == "default.cshtml" ?
            "Microsoft.AspNetCore.Mvc.Razor.RazorPage<System.Net.HttpStatusCode>" :
            "Microsoft.AspNetCore.Mvc.Razor.RazorPage";

        var projectFileSystem = RazorProjectFileSystem.Create("../Cnblogs.Web.ErrorPages/Views/Errors/");
        var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, projectFileSystem, builder =>
        {
            builder
                .SetNamespace("Cnblogs.Web.ErrorPages")
                .SetBaseType(baseType)
                .ConfigureClass((doc, @class) =>
                    {
                        @class.ClassName = "Error" + Path.GetFileNameWithoutExtension(filename);
                    });
        });

        RazorProjectItem projectItem = projectFileSystem.GetItem(filename, null);
        RazorCodeDocument razorDocument = projectEngine.Process(projectItem);
        RazorCSharpDocument csDocument = razorDocument.GetCSharpDocument();
        string csString = csDocument.GeneratedCode;
        var targetFilePath = projectItem.PhysicalPath.Replace(projectItem.Extension, ".Designer.cs");
        File.WriteAllText(targetFilePath, csString);
    }
}
dudu的主页 dudu | 高人七级 | 园豆:30925
提问于:2019-07-02 10:27

这个有意义?如果只是要结果,发布时候可以在dll里

张朋举 5年前

@张朋举: nuget 打包给各个项目使用

dudu 5年前
< >
分享
所有回答(3)
0

你是想做什么?编译cshtml到dll里??

心雨纷扬 | 园豆:309 (菜鸟二级) | 2019-07-03 11:23

是的,在不使用 razor class library 的情况下将 cshtml 编译到 dll 中

支持(0) 反对(0) dudu | 园豆:30925 (高人七级) | 2019-07-03 11:27

@dudu: 你试过发布?我发布过release的,自动会打包cshtml文件到dll
我用的是preview6
https://blog.csdn.net/sD7O95O/article/details/89391586
不太确定你的需求是不是这种

支持(0) 反对(0) 心雨纷扬 | 园豆:309 (菜鸟二级) | 2019-07-03 11:37

@心雨纷扬: 我要发布为 nuget 包给其他项目使用

支持(0) 反对(0) dudu | 园豆:30925 (高人七级) | 2019-07-03 13:41

@dudu:
我这里是可以把web项目发布nuget包,并使用的,如果不考虑静态资源文件路径问题。但是好像没啥意义
其实我不太确定你的具体场景, razor class library应该是最方便的方式呀。

支持(0) 反对(0) 心雨纷扬 | 园豆:309 (菜鸟二级) | 2019-07-03 14:27

@心雨纷扬: 现在就是用的就是 razor class library ,但如果引用这个 razor class library 的 web 项目发布时没有预编译视图,就会找不到 razor class library 中的视图

支持(0) 反对(0) dudu | 园豆:30925 (高人七级) | 2019-07-03 17:19

@dudu: 可以参考Abp VNext

源码

有类似的实现。

支持(0) 反对(0) 心雨纷扬 | 园豆:309 (菜鸟二级) | 2019-07-05 10:30

@dudu:
调用

public async Task SendHelloWorldEmail(string email, string name){
  string template = "Templates.HelloWorldTemplate";
  RazorParser renderer = new RazorParser(typeof(EmailClient).Assembly);
  
  var body = renderer.UsingTemplateFromEmbedded(template,new   HelloWorldViewModel { Name = name });
  
  await SendEmailAsync(email, "Email Subject", body);
}

获取路径

    public class RazorParser
    {
        private Assembly _assembly;
        public RazorParser(Assembly assembly)
        {
            this._assembly = assembly;
        }

        public string Parse<T>(string template, T model)
        {
            return ParseAsync(template, model).GetAwaiter().GetResult();
        }

        public string UsingTemplateFromEmbedded<T>(string path, T model)
        {
            var template = EmbeddedResourceHelper.GetResourceAsString(_assembly, GenerateFileAssemblyPath(path, _assembly));
            var result = Parse(template, model);

            return result;
        }

        async Task<string> ParseAsync<T>(string template, T model)
        {
            var project = new InMemoryRazorLightProject();
            var engine = new EngineFactory().Create(project);

            return await engine.CompileRenderAsync<T>(Guid.NewGuid().ToString(), template, model);
        }

        string GenerateFileAssemblyPath(string template, Assembly assembly)
        {
            string assemblyName = assembly.GetName().Name;
            return string.Format("{0}.{1}.{2}", assemblyName, template, "cshtml");
        }
    }
支持(0) 反对(0) 心雨纷扬 | 园豆:309 (菜鸟二级) | 2019-07-05 13:53
0

大佬,你的问题解决了么?我现在也碰到了这样的问题,请问怎么把cshtml文件转换为cs代码来给中间件进行输出呢?

鱿鱼丝儿 | 园豆:206 (菜鸟二级) | 2021-07-25 18:35

不需要转换,中间件是可以直接输出视图文件的,建议在博问中专门发一个提问

支持(0) 反对(0) dudu | 园豆:30925 (高人七级) | 2021-07-25 19:25
0

好像,没有办法 解析 layout 模板视图,找不到 这样

十色 | 园豆:210 (菜鸟二级) | 2021-10-24 14:34
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册