Print and/or modify the c# version that the razor

2019-06-15 02:56发布

I'd like to be able to find out which C# version razor uses to compile my cshtml templates. The reason why I want this, is this breaking change.

We had a lambda in a foreach statement that worked fine on our local dev machines but produced a bug on our test environment (which doesn't have C# 5 installed). This bug was VERY hard to debug (we even copied all the test environment DLLs and databases and were still not able to reproduce the bug).

So to prevent this dev/test difference in the future I would like to know if there's a way to specify the C# version that razor should be using to compile cshtml files. It would also be nice if I could check the C# version that razor uses (by printing it).

Update: As requested, more details on how this behavior occurred.
We use a devexpress mvc grid to display data in our razor views. To add columns in a dynamic way we loop (foreach) a list which inserts columns in the datagrid (using a lambda). A simplified example:

@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);
                });
            });
        }
    });

1条回答
我命由我不由天
2楼-- · 2019-06-15 03:06

The version of razor is specified on the Web.config file within the Views directory. It has to match one of the versions on the dependent assemblies list for the System.Web.WebPages assembly. This entry is on the main Web.config file (usually located at the root of your application tree)

Retrieving data from config files is fairly simple. See the ConfigurationManager class for this. If you'd like to do it at runtime.

It's also possible to determine the Razor version based on the referenced assemblies of your application. You could use reflection for that, here's a snippet that spits out all the referenced assemblies:

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

Obviously there might be performance implications based of the method you choose to evaluate this info at runtime.

Update 1

From the comments below I take that when you mention compilation you refer to the Razor view parsing process at compile time. There are other concepts of "Razor View Compilation" see Razor Generator, regardless of which one you do mean both rely on the reference to the System.Web.WebPages assembly which contains the library dependencies for the Razor View Engine itself. So if you know which assembly you are pointing at, you know which version of Razor you are using.

Update 2

Taking into account that you are worried about conflicts with the version of C# that you use in your views, you should use the following rule of thumb: You should always reference the DLL (System.Web.WebPages) that targets the framework you are using. It's important to remember that the MVC framework has a different update timeline than the language itself. A good example is the async keyword, it was added to the language first and later adopted by the MVC framework. Usually new versions of the .NET Framework are backwards compatible 'til version 2.0 and when you use deprecated stuff you get compilation warnings. If you'd like to use older versions of the framework while compiling you can always resort to changing the target framework on your IDE.

In addition to getting your references and target framework right, remember that when you setup Web applications in IIS you specify an application pool tied to the framework version. You might be using new features of the .NET framework, and you might expect for them to work because you have the new version installed, but your application is running in an application pool of a different version.

Before having this nasty mixup between DLL & Frameworks versions I'd follow upgrade guidelines taking into account that some of the code I implemented with the previous version might not work properly with the new one.

Update 3

Here's some code to retrieve your CLR version at Runtime as described in MSDN.

// Get the common language runtime version.
Version ver = Environment.Version;
Console.WriteLine("CLR Version {0}", ver.ToString());
查看更多
登录 后发表回答