Expression Evaluation in Local Mode

RDL and RDLC files contain expressions written in VB.Net.  As .Net code, expressions can potentially perform any operations, including accessing the file system or running native code.  Code access security (CAS) for expressions is therefore critically important.

When a report is deployed to a report server, the report definition goes through a publishing phase that extracts the expressions and compiles them into an assembly.  The assembly, often referred to as the expression host assembly, is then used when the report is executed to evaluate the expressions.  When using local mode, the same process happens in memory when a report definition is supplied to LocalReport.

Visual Studio 2005 and 2008

In Visual Studio 2005 and 2008, there are two ways to load the expression host assembly: into the current AppDomain or into a sandbox AppDomain.

Loading the expression host into the current AppDomain means that it is loaded into the same AppDomain in which the ReportViewer is running.  This has an advantage of improved performance as well as giving you more flexibility over the CAS policy.  Since you create the AppDomain in which the viewer runs, you can also grant a specific set of permissions to any external assemblies loaded by the expression host.  One clear disadvantage, however, is that the assembly will not be unloaded until the entire AppDomain is unloaded, typically when the application shuts down.  If you process lots of reports during in your application, the result is in an effective memory leak each time a new report is processed.  This may be ok for a short lived winforms application that displays a small number of reports, but it doesn’t make as much sense for an ASP.Net application.

Running in the current AppDomain is the default.  However, if you have switched to another mode, you can switch back using ExecuteReportInCurrentAppDomain.  If your report references external assemblies, the viewer will not load them unless you specifically allow it via AddTrustedCodeModuleInCurrentAppDomain.

The sandbox AppDomain is a more restrictive environment for evaluating expressions.  Any assembly loaded into the sandbox AppDomain is granted only Execution permission.  You can switch execution to the sandbox using ExecuteReportInSandboxAppDomain.  In theory, using a separate AppDomain prevents the memory leak.  However, due to the implementation of the sandbox AppDomain in the VS 2005 and 2008 report viewers, the sandbox AppDomain is not unloaded.

Visual Studio 2010

The ReportViewer in VS 2010 is a multi-targeted assembly.  That means that is can be loaded into a .Net 3.5 or a .Net 4.0 application.  When running under .Net 3.5, all of the same rules and methods noted above are applicable.  However, the CLR security team made changes to code access security in .Net 4.0, so there are corresponding changes in the ReportViewer as well:

  • Executing in the current AppDomain is no longer supported, so using a sandbox is the default mode when running in .Net 4.0.  Two new methods have been added to better control the permissions of the sandbox AppDomain so that you don’t see any loss of functionality:  AddFullTrustModuleInSandboxAppDomain and SetBasePermissionsForSandboxAppdomain.
  • ExecuteReportInCurrentAppDomain, AddTrustedCodeModuleInCurrentAppDomain, and ExecuteReportInSandboxAppDomain have been marked as obsolete.  While it is perfectly acceptable to use them in a .Net 3.5 application, they won’t have any effect when you compile for .Net 4.0.  Going forward, we recommend using the sandbox AppDomain even under .Net 3.5 because setting the correct security policy on the current AppDomain is an error prone task.  The new methods will work under both frameworks and is the best approach if you want to write in a framework agnostic way.

If you do nothing, the default behavior under .Net 4.0 will result in the same permissions for the expression host as the default behavior in VS 2008.  You will be running in a sandbox AppDomain (versus the default of the current AppDomain in VS 2008), but the permissions for the expression host will be the same.

As part of the security changes to the CLR in .Net 4.0, an application configuration flag, NetFx40_LegacySecurityPolicy, can be specified to use the .Net 3.5 security model in .Net 4.0.  If this flag is specified, the report viewer will behave just as it would under .Net 3.5, meaning that the obsolete methods will function correctly.

Regardless of which framework version you use with the VS 2010 report viewer, the issue surrounding the sandbox AppDomain leak has been fixed.  The sandbox AppDomain is shared resource across multiple instances of the viewer.  A new AppDomain is created periodically (if there is a need) and used by all local mode requests in the process.  Once all reports referencing the old AppDomain have completed, the old domain will unload.