报表查看器 - 请求SqlClientPermission类型的权限失败

6

我正在使用Visual Studio 2008中的ReportViewer控件,以对象作为数据源。我的类映射到数据库中的数据表。在对象中,它根据需要加载相关对象,因此它将引用为空,直到您尝试使用属性,然后它会自动从数据库中加载它。这些类使用System.Data.SqlClient命名空间。

当我在Windows Forms应用程序中与对象交互时,一切正常。但是当我将对象传递给用作报告数据源的对象,并尝试自动加载相关对象时,它失败了。该代码创建一个SqlConnection对象,并在调用GetCommand()时抛出以下异常:

[System.Security.SecurityException] {
"Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed."
} System.Security.SecurityException

我尝试搜索错误信息,但所有出现的结果都是关于在SQL Server或ASP.Net上运行CLR程序集的。我尝试在创建SqlConnection对象之前添加以下调用(如搜索结果中建议的),但似乎没有任何作用:

System.Data.SqlClient.SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted).Assert();

有什么想法吗?
5个回答

7
除了CuppM的回答之外,ExecuteReportInCurrentAppDomain方法自.NET4起已被弃用,应该使用LocalReport.SetBasePermissionsForSandboxAppDomain代替,因为ReportViewer现在总是在沙盒域中执行。
PermissionSet permissions = new PermissionSet(PermissionState.None);
permissions.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
ReportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(permissions);

请点击此处查看详细信息。


谢谢。我刚刚花了五个小时左右摸索,试图弄清楚为什么我的报告没有按预期显示。这解决了我的“#Error”问题。 - Rob Gray
这并没有任何区别,唯一有效的方法是将其添加到web.config中,而我不被允许这样做。 - montelof

4
我找到了解决方案。您需要指定执行程序集(或具有足够权限的程序集)的 System.Security.Policy.Evidence 以供在执行过程中使用 LocalReport。
reportViewer.LocalReport.ExecuteReportInCurrentAppDomain(System.Reflection.Assembly.GetExecutingAssembly().Evidence);

1

以防万一有人像我一样在寻找Permission-Error时偶然发现了这篇文章。 我在使用 Windows-Forms-Application 时遇到了这个错误,因为客户在他的机器上使用"\COMPUTERNAME\C$\Application.exe"而不是"C:\Application.exe"链接了我的应用程序Exe的快捷方式。 这导致了 System.Security.Permission 失败,因为它是不受信任的内部网络使用。

更多信息请参见http://www.duelec.de/blog/?p=236


1

Artem在上面的回答中提到了一个注脚...

当我将Windows身份验证添加到我的asp.net应用程序中时,我遇到了这个问题。目标框架为4.5,并使用报表组件11。当我允许匿名用户(在早期开发中)时,使用ReportViewer没有任何问题。一旦启用Windows身份验证,无论是在分组表达式上得到“#Error”,还是根本无法运行报告,都会出现上面列出的异常。

我能够通过稍微修改Artem发布的代码来解决问题。除了一般意义上允许CAS信任沙箱化的ReportViewer代码之外,我并不完全确定代码的作用。如果有人能简要解释一下,那就太好了。

    Dim permissions As PermissionSet = New PermissionSet(PermissionState.Unrestricted)
    myReportViewer.LocalReport.SetBasePermissionsForSandboxAppDomain(permissions)

这是我的代码实际使用的内容,而不是Artem使用的更细粒度的方法。除了作为一个单独的语句。 - CuppM

0
一个快速的想法,尽管我没有看到这个错误,但确保您的Assert与设置资源数据源的代码位于同一个方法中。
System.Data.SqlClient.SqlClientPermission mPermission = new SqlClientPermission(System.Security.Permissions.PermissionState.Unrestricted);
try
{
    mPermission.Assert();
    //rest of your code
}
//Handle Exceptions

权限断言不会持续很长时间,它们可能是安全问题,因此在尽可能靠近需要它们的代码处执行它们最有可能起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接