【问题标题】:Print and/or modify the c# version that the razor compiler service uses to compile cshtml打印和/或修改 razor 编译器服务用于编译 cshtml 的 c# 版本
【发布时间】:2014-02-24 15:26:41
【问题描述】:

我希望能够找出 razor 使用哪个 C# 版本来编译我的 cshtml 模板。我想要这个的原因是this breaking change

我们在 foreach 语句中有一个 lambda,它在我们的本地开发机器上运行良好,但在我们的测试环境(没有安装 C# 5)上产生了一个错误。这个错误非常难以调试(我们甚至复制了所有测试环境的 DLL 和数据库,但仍然无法重现该错误)。

因此,为了防止将来出现这种开发/测试差异,我想知道是否有办法指定 razor 用于编译 cshtml 文件的 C# 版本。如果我可以检查 razor 使用的 C# 版本(通过打印它),那就太好了。

更新:根据要求,提供有关此行为如何发生的更多详细信息。
我们使用 devexpress mvc 网格在我们的 razor 视图中显示数据。为了以动态方式添加列,我们循环(foreach)一个在数据网格中插入列的列表(使用 lambda)。一个简化的例子:

@Html.DevExpress().GridView(
    settings =>
    {
        settings.Name = "gvDashboard";
        //Some more settings

        settings.Columns.Add(column =>
        {
            column.FieldName = Model.DashboardItems.PropertyName(p => p.Id);
            column.Caption = "Id";
            //Some more column settings
        });

        foreach (var extraColumnLoopVar in Model.ExtraColumns)
        {
            //We added this to solve the problem
            var extraColumn = extraColumnLoopVar; 

            settings.Columns.Add(column =>
            {
                column.Caption = extraColumn.Name;
                //Some more column settings

                column.SetDataItemTemplateContent(content =>
                {
                    Html.ViewContext.Writer.Write(extraColumn.MyValue);
                });
            });
        }
    });

【问题讨论】:

  • 很好奇你所依赖的循环关闭的用途。正如文章所提到的,它很少被实际使用。所以我真的很想看到这样一个用例。
  • 查看更新的答案
  • 感谢您花时间更新您的问题。我以为您实际上使用了 闭包变量行为,但是您遇到了您不想 想要使用它的问题。看起来这会咬很多不知道即将成为传统设置中不同行为的人。由于您的问题,我确实了解了这一重大变化;)
  • 你说得对,我把这个例子简化了。我确实使用了该值,并且在 C# 4 中,每列的值都相同。 PS。我很高兴你从中学到了:)。

标签: c# razor razorgenerator


【解决方案1】:

razor 的版本在 Views 目录中的 Web.config 文件中指定。它必须与 System.Web.WebPages 程序集的依赖程序集列表上的版本之一匹配。此条目位于主 Web.config 文件中(通常位于应用程序树的根目录)

从配置文件中检索数据相当简单。请参阅ConfigurationManager 课程。如果您想在运行时执行此操作。

还可以根据应用程序的引用程序集确定 Razor 版本。您可以为此使用反射,这里有一个 sn-p,它会吐出所有引用的程序集:

var sb = new StringBuilder();
Assembly asm = Assembly.GetExecutingAssembly();
sb.AppendLine("File Version:");
sb.AppendLine(asm.FullName);

sb.AppendLine("References :");
AssemblyName[] asmNames = asm.GetReferencedAssemblies();
foreach (AssemblyName nm in asmNames)
{
    sb.AppendLine(nm.FullName);
}

// use sb.ToString() to print out wherever you need to

显然,根据您选择在运行时评估此信息的方法,可能会对性能产生影响。

更新 1

从下面的 cmets 中,我认为当您提到编译时,您指的是编译时的 Razor 视图解析过程。 “Razor 视图编译”还有其他概念,请参阅Razor Generator,无论您的意思是哪一个都依赖于对 System.Web.WebPages 程序集的引用,该程序集包含 Razor 视图引擎本身的库依赖项。因此,如果您知道您指向的是哪个程序集,那么您就知道您使用的是哪个版本的 Razor。

更新 2

考虑到您担心与您在视图中使用的 C# 版本发生冲突,您应该使用以下经验法则:您应该始终引用以框架为目标的 DLL (System.Web.WebPages)您正在使用。重要的是要记住,MVC 框架的更新时间线与语言本身不同。一个很好的例子是 async 关键字,它首先被添加到语言中,后来被 MVC 框架采用。通常,新版本的 .NET Framework 向后兼容直到 2.0 版,当您使用不推荐使用的东西时,您会收到编译警告。如果您想在编译时使用旧版本的框架,您可以随时在 IDE 上更改目标框架。

除了让您的引用和目标框架正确之外,请记住,当您在 IIS 中设置 Web 应用程序时,您会指定一个与框架版本相关联的应用程序池。您可能正在使用 .NET 框架的新功能,并且您可能希望它们能够正常工作,因为您安装了新版本,但您的应用程序在不同版本的应用程序池中运行。

在 DLL 和框架版本之间出现这种令人讨厌的混合之前,我会遵循升级指南,考虑到我用旧版本实现的一些代码可能无法在新版本中正常工作。

更新 3

这里有一些代码用于在运行时检索您的 CLR 版本,如 MSDN 中所述。

// Get the common language runtime version.
Version ver = Environment.Version;
Console.WriteLine("CLR Version {0}", ver.ToString());

【讨论】:

  • 是的,这样我可以获取/设置 Razor 的版本,但这是否与 razor 用于编译我的视图的 C# 版本有关?
  • 你是如何准确地编译你的观点的?
  • 无论您以何种方式编译它们,您的视图都必须在任何地方使用相同的 dll。所以我不明白你的问题。
  • 这与 dll 无关,而是 razor 将 c# 编译为二进制文件的方式导致了问题(请参阅 OP 中的重大更改链接)。 Razor 使用它自己的编译器服务组件来动态编译视图。
  • 阅读您的更新后,“编译时间”是什么意思。因为我的 csharp 代码文件是在编译时编译的,而我的 razor 视图是在运行时编译的。为了更清楚地说明这一点:我不关心使用哪个 Razor 版本,我只关心使用的 C# 版本(我希望我的视图在 C# 4 而不是 C# 5 中编译)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 2018-10-18
相关资源
最近更新 更多