您的位置:首页 > 其它

通过 Microsoft 报告服务使 Web 应用程序具有报告功能

2006-07-04 23:41 288 查看
Teo Lachev

报告是现今几乎所有 Web 应用程序的不可缺少的组成部分。但是,尽管用于创建此类应用程序的工具已经完善,但 Web 报告却经常简单地归结为生成 HTML 表形式的表格式报告。Microsoft SQL Server 2000 报告服务弥补了这一缺陷,并且提供了必要的工具以便容易地使 Web 应用程序具有报告功能。本文改编自 Teo Lachev 的著作Microsoft Reporting Services in Action。在本文中,作者说明了如何利用报告服务在 ASP.NET 应用程序的服务器端生成报告。



本页内容


集成选择


应用程序体系结构


部署视图


保护应用程序


请求服务器端报告


ReportViewerEx Web 控件


服务器端属性


处理报告图像


根据 ADO.NET 数据集报告


呈现报告


小结


备注:资源
假设您已经被指派为设计和实现 Internet 电子商务 Web 站点的首席开发人员。除了提供其他功能以外,应用程序还必须提供满足下列要求的全面的报告功能:

客户端零部署。

服务器端报告生成。例如,业务规则可能需要评估,或者用户需要进行身份验证。

对多种导出格式(例如,HTML、PDF 等等)的支持。

对根据自定义数据结构进行报告的支持。例如,应用程序演示层可能需要根据从应用程序业务层检索的 ADO.NET 数据集生成报告。

乍看起来,该功能集可能有点儿令人害怕。的确,在报告服务问世之前的时代,您的选择被限制为实现自定义的报告解决方案或者购买昂贵的第三方报告工具。让我们看一下通过将应用程序与 Microsoft SQL Server 2000 报告服务(在本文的其余部分一律称为“RS”)相集成来满足这些要求是多么容易。

集成选择

报告服务的最突出的功能之一是,默认情况下基于 RS 的报告支持 Web。在将报告部署到报告目录以后,客户端就可以通过 RS 提供的两个 Web 外观中的一个来请求该报告:

HTTP 处理程序(URL 可寻址性)— 通过提交 HTTP-GET 请求以指定报告 URL 地址。例如,要请求 Product Catalog 报告(RS 示例报告之一),客户端可以提交下列报告请求:

http://ServerName/ReportServer?/SampleReports/ Product Catalog

 RS Web服务— 通过向 RS Web 服务提交 SOAP 请求。RS 通过 Web 服务公开它的完整功能集以支持多种多样的集成方案。例如,您可能需要以编程方式生成报告并将其上载到报告目录。在这种情况下,只要生成了报告定义文件(通过使用 XML DOM),客户端就可以调用 CreateReport SOAP API。

根据在 RS 新闻组 (microsoft.public.sqlserver.reportingsvcs) 上张贴的问题判断,很多开发人员不能肯定应该选择哪个实现。 1 总结了有关选择。

表 1. URL 与 RS Web 服务之比较。
功能URL 可寻址性 (HTTP-GET)Web 服务 (SOAP)
实现
在应用程序的客户端将报告请求直接提交给报告服务器。对于 Internet 报告,必须可以在 Internet 上访问报告服务器。
对于基于 Web 的应用程序,报告请求通常是在应用程序的服务器端提交的。
功能
仅限于请求报告。
公开所有 RS 功能,包括请求报告、管理报告目录、订阅传递等等。
交互功能(追溯、深入挖掘、等等)
可以。
不可以。
HTML 查看器工具栏
可用。
不可用。
集成难易程度
容易。可以像在超链接中对报告 URL 地址进行硬编码一样容易。
比较困难。需要关心显式下载报告图像、处理报告参数以及将报告呈现给最终用户等问题。
安全性
基于 Windows 的身份验证(Intranet 报告)或表单身份验证(Internet 报告)。
通常为基于 Windows 的身份验证。
安全漏洞
恶意的用户可以查看和利用报告请求。
更安全,因为报告完全是在服务器端生成的。
灵活性
灵活性较低。
灵活的集成方案 — 例如,根据 ADO.NET 数据集报告、评估业务规则、无人参与的报告生成等等。
性能
更好。
报告有效负载需要在服务器端序列化为字节数组,并且需要在客户端反序列化。
通常,不管应用程序类型是基于 WinForm 还是 Web 的,只要有可能,您都应当倾向于按 URL 请求报告,因为它更容易实现并且提供了更好的性能。此外,它通过支持所有交互功能(包括有用的 HTML 查看器工具栏)提供了更好的用户体验。工具栏可以通过处理琐碎的报告任务(例如,参数处理、分页、缩放、搜索文本等等)为您节省很多精力。但是请注意,通过 URL 可寻址性,报告请求在应用程序的客户端直接提交给报告服务器。结果,您通常缺少对预处理报告请求的控制 — 例如,您无法评估业务规则或者根据只在应用程序的服务器端可用的数据结构进行报告。

有时,您的需求将决定访问方法。例如,您在评估这两个集成选择时必须询问自己的首要问题之一是:“对于我的用户而言,报告交互性功能有多么重要?”如果报告交互性是必需的,则 URL 访问是唯一的选项。对于 Internet 报告而言,这几乎意味着必须将默认的基于 Windows 的 RS 身份验证替换为自定义安全实现。如果您决定采用这一路线,则请参阅接近本文结尾处的“资源”备注,并寻找指向 Microsoft Forms Authentication 示例(该示例教您如何完成上述工作)的链接。

通常,严格的安全性和业务需求会要求通过向下调用到 RS Web 服务在服务器端生成报告。在本文的其余部分中,我将说明我所开发的 ReportViewerEx Web 控件如何使这一努力变得更加容易。



返回页首

应用程序体系结构

在我们的假设示例中,我们将假定一家虚构的名为 Adventure Works Cycles 的公司(其示例数据库随附在 RS 和 SQL Server 2005 中)已经决定实现基于 Internet 的企业到消费者 (B2C) 电子商店,以便联机销售它的产品。就像很多商务应用程序所常见的那样,电子商店的需求之一是使客户可以生成订单历史记录报告,以显示该客户已经下了哪些订单。



返回页首

部署视图

让我们假设电子商店 Web 应用程序已经就绪,并且它被设计为标准的分布式应用程序,如 1 所示。

我们的需求如下:

应用程序负责对用户进行身份验证。为了满足该需求,我们的示例应用程序利用了 ASP.NET 表单身份验证。

在用户提交了报告请求页以后,应用程序立即对报告请求进行验证。(为了保持简单性,我们不会实现任何业务规则验证,但是在实际情况下,您很可能需要在生成报告之前调用业务层来验证报告请求。)

在验证报告请求之后,应用程序将立即准备报告请求并将其提交给报告服务器。



返回页首

保护应用程序

RS 安全模型乍看起来可能令人畏惧。正如我在前面提到的那样,RS 默认情况下使用基于 Windows 的安全来对报告请求进行身份验证,但是您的需要可能排除该选择。例如,生成服务器端报告的 Intranet Web 应用程序可能通过将用户凭据传递给报告服务器来模拟用户。但是,Internet 应用程序通常会排除基于 Windows 的身份验证。(只须想象一下,如果您必须创建和维护成千上万个用户帐户,则维护工作量该有多大。)

一种优秀的身份验证模型是选择所谓的受信任的子系统 方法,其中应用程序将它的标识传递给报告服务器。由于应用程序负责对报告请求进行身份验证和授权,因此您可以通过将报告服务器配置为将最少的权利授予受信任的子系统帐户(将用于运行应用程序的帐户),简化安全基础结构。例如,如果应用程序需要的全部功能是报告生成,则可以将应用程序标识帐户“浏览器”权限授予报告目录。

使用受信任的子系统方法的另一个优点是,应用程序可以使用相同的标识来针对支持 Windows 集成身份验证的数据源(例如,SQL Server)进行身份验证。相对于使用标准的数据库安全而言,这可以提供附加级别的安全性,因为您在打开连接时无须传递凭据。出于上述原因,我们将使用受信任的子系统方法。请参考源代码中的自述文件,以获得分步配置说明。



返回页首

请求服务器端报告

为了说明 Web 应用程序如何与 RS 集成以在服务器端生成报告,我创作了一个名为 Customer Orders 的示例报告(参见 2)。

报告本身没有什么了不起的;它是一个简单的表格式报告 — 给定一个客户标识符,它通过查询 AdventureWorks2000 数据库来显示该客户的订单历史记录。使该报告有趣的方面是它的生成方式。可以通过调用 Render SOAP API(它是 RS Web 服务公开的 API 之一)在服务器端生成报告。一般来说,通过 RS Web 服务生成报告要比 URL 可寻址性更为复杂一些,因为它需要完成一些额外的预处理和后续处理步骤。特别地,您需要:

1.

实例化 RS Web 服务代理并配置它的安全凭据。如果您需要将调用方标识传递给报告服务器(或者在我们的示例中,传递受信任的子系统标识),则可以简单地按如下方式设置代理:

rs.Credentials =
System.Net.CredentialCache.DefaultCredentials;

2.

设置 Render 方法参数并调用该方法。

3.

在以 HTML 格式呈现报告时,处理报告图像。当浏览器加载带有图像的页时,它会跨越其他 HTTP-GET 请求以获取这些图像。因此,您需要将这些图像显式下载到浏览器可以在其中找到它们的文件存储区。

4.

将报告呈现给最终用户。例如,如果报告需要在 ASP.NET 页上就地呈现(嵌入式),则您可以通过发送一个名为 HTMLFragment 的特殊设备设置,指示报告服务器抽析出 HTML、HEAD 和 BODY 标记。如果报告是以另一个格式请求的,则可以将报告有效负载流式传输到浏览器,而后者将用常见的“File Download”对话框响应。

您还可能需要关心其他一些任务,具体取决于您的需求 — 例如,将报告请求与缓存的报告会话相关联、处理报告参数等等。

正如您可以看到的那样,通过 RS Web 服务生成报告可能变得很复杂。但不用担心。为了简化该过程,我开发了一个名为 ReportViewerEx 的 Web 控件。尽管您无须 使用 Web 控件使应用程序具有报告功能,但我仍然决定使用该方法,因为它将报告生成逻辑封装在一个可以在运行时和设计时配置的可重用类中。



返回页首

ReportViewerEx Web 控件

我为什么称之为 ReportViewerEx 呢?嗯,因为它增强了 Report Viewer 控件(随附于 Report Server,作为 Sample 的一部分)的能力。也许您有所耳闻,RS Report Viewer 使开发人员能够在服务器端配置控件(报告路径、报告服务器 URL 和报告特定的参数),而实际的请求由 URL 在客户端产生。

正如我说过的那样,如果您的报告需求支持 URL,则有充分的理由选择它。特别地,它尤其适合于 Intranet Web 应用程序 — 对于此类应用程序而言,基于 Windows 的安全是可行的且理想的。尽管 Internet 应用程序也可以利用该控件(以及 URL 可寻址性),但后者大多需要自定义安全性。



返回页首

服务器端属性

然而,在我们的示例中,Adventure Works 报告需求拒绝对报告服务器进行直接访问。因此,我用其他属性(参见 2)增强了 ReportViewer 控件,以支持服务器端报告生成(参见 3)。

表 2. ReportViewerEx 服务器端属性。
属性类型可用性用途
DataSource
System.Data.DataSet
仅运行时
设置为 ADO.NET 数据集的实例,以便根据应用程序数据集进行报告。
ServerSide
Boolean
设计时/运行时
设置为 true 以便在服务器端生成报告。
ImageDownloadPath
String
设计时/运行时
指定要将报告图像下载到的位置。该路径相对于应用程序根路径。
StreamRoot
String
设计时/运行时
指定图像处理程序页的 URL 位置。
最重要的属性是 ServerSide 属性。当设置为 false(或 Default)时,它使 ReportViewerEx 控件的行为类似于 RS ReportViewer 控件。(为了实现这一点,我将原始的 ReportViewer 代码保留不变。)当 ServerSide 被设置为 true 时,ReportViewerEx 控件在服务器端生成报告(稍后将对此进行详细讨论)。请注意,对于 ReportViewerEx 的当前实现,ImageDownloadPath 属性需要相对于应用程序的根路径。但是,您完全可以更改该控件,以使其将报告图像文件保存到某个绝对路径或文件共享。



返回页首

处理报告图像

正如我在前面解释的那样,当通过 SOAP 以 HTML 格式呈现报告时,需要显式下载报告图像,并且您可以通过为每个图像迭代调用 RenderStream SOAP API 完成该工作。为了获得最大的灵活性,我决定实现一个 ASP.NET 图像处理程序页。这样做的优点是,该图像处理程序可以在图像呈现之后立即删除该图像。

要将页 URL 传递给 ReportViewerEx,可以使用 StreamRoot 控件属性。如果将该属性保留为空白,则它默认为 ImageDownloadPath 属性。您通常会使用以下语法将 StreamRoot 设置为指向图像处理程序页 URL:

http:////
ImageHandler.aspx?ID=

当报告被处理时,报告服务器将分析 StreamRoot 设置并相应地调整图像 URL。(特别地,它会将图像流标识符追加到 URL 字符串的末尾。)当报告在客户端呈现时,浏览器将调用图像处理程序页,并且将该流标识符作为查询参数传递。

图像处理程序页 (ImageHandler.aspx) 位于 AwReporterWeb 项目根目录中。该页试图从应用程序配置文件中指定的位置加载图像。由于 AWReportViewer 和图像处理程序可能驻留在不同的 Web 应用程序中,因此您需要确保两者都被配置为使用相同的图像存储区。



返回页首

根据 ADO.NET 数据集报告

我尚未解释的最后一个属性是 DataSource 属性。它使应用程序可以将 ADO.NET 数据集的实例传递给 ReportViewerEx,以便将该数据集“绑定”到报告,就像可以将 ADO.NET 数据集绑定到 ASP.NET 控件一样。由于报告服务的版本 1.0 本身不支持根据 ADO.NET 数据集报告,因此我编写了一个自定义数据集扩展(请参阅“资源”备注)。对该扩展进行讨论超出了本文的范围,但是我建议您参考下载中的自述文件,以了解有关配置和使用 ADO.NET 数据扩展的详细信息。



返回页首

呈现报告

ReportViewerEx 控件报告生成逻辑的首要因素是 Render 方法。在设计时或运行时,当报告需要呈现时,ASP.NET 框架将调用该方法。为了使事情变得简单一些,在设计时,控件只是显示以下信息性消息:

To render a report, enter the ServerUrl and ReportPath.

当控件在运行时呈现并且 ServerSide 属性被设置为 True 时,将发生完整的报告生成操作,如清单 1 所示。

清单 1. 呈现服务器端报告。

byte[] result = RenderReport();
if (IsHtmlReport)  {
string res = Encoding.UTF8.GetString(result);
output.Write(res);
}
else {
HttpResponse response=
System.Web.HttpContext.Current.Response;
response.ClearContent();
response.ClearHeaders();
string fileName =
GetFileName(this.ReportPath, this.Format);
response.ContentType =
GetContentType(Path.GetExtension(fileName));
response.AddHeader ("content-disposition",
"attachment;    filename=/"" + fileName + "/"");
response.BinaryWrite(result);
response.Flush();
response.Close();
}

首先,我调用 RenderReport Helper 函数以通过 SOAP 生成报告。该过程类似于 RS 文档中的 Render SOAP API 代码示例,因此这里我不会花费很多时间来讨论它。在研究 RenderReport 函数时,请注意,在通过 Render SOAP API 呈现报告之后,当报告被以 HTML 格式请求时,代码将反复调用 RenderStream SOAP API 以下载报告图像。

如果所请求的格式是 HTML 格式之一(例如,HTML4.0、HTML3.2 或 HTMLOWC),则报告被呈现为 HTML 片段。ReportRender 函数通过将 HTMLFragment 设备设置发送到 ReportServer 做到这一点。

如果导出格式是除 HTML 以外的某种格式,则 ReportViewerEx 会将报告有效负载流式传输到浏览器。为了实现该功能,我们首先清除响应缓冲区。然后,我们让浏览器知道响应流的类型 — 例如,对于 Adobe PDF,类型为“application/pdf”。我们还需要指定文件名 — 我们将其默认为报告名称,并且带有相应于指定导出格式的适当的文件扩展名。(尽管 default.aspx 页不允许用户选择除 HTML 以外的报告格式,但您可以容易地增强该页,以询问用户首选格式是什么,并且相应地设置 ReportViewerEx 控件 Format 属性。)

最后一个值得更多注意的领域是控件属性同步。正如我在前面提到的那样,该控件具有内置逻辑,以确定哪些属性可用于服务器端模式和客户端模式。为了实现该功能,我必须实现 ICustomTypeDescriptor 接口并重写该控件的属性说明符。



返回页首

小结

报告服务提供了两个集成选择 — URL 可寻址性和 RS Web 服务 — 以满足多种多样的集成方案。尽管 URL 可寻址性是首选的集成选择,但有时,严格的安全或其他需求可能要求使用 RS Web 服务。当需要在 Web 应用程序的服务器端生成报告时,就是这种情况。

尽管非常灵活,但通过 RS Web 服务生成报告要比使用 URL 可寻址性更复杂一些。我希望,借助于 ReportViewerEx 控件以及您在本文中发现的知识,您能够满怀信心地(甚至迫切地)去解决这些复杂性。

最后,您应当知道,下一个版本的报告服务(计划与 SQL Server 2005 一起发布)将包含能够使集成 .NET 应用程序变得更加容易的 WinForm 和 ASP.NET 控件。



返回页首

备注:资源

报告服务新闻组 — microsoft.public.sqlserver.reportingsvcs

“Using Forms Authentication in Reporting Services”白皮书 — 如果您希望为 Internet 应用程序实现 URL 报告可寻址性,则可能需要将默认的基于 Windows 的 RS 安全替换为自定义的身份验证。这一优秀的白皮书将向您说明如何完成该工作。 http://msdn.microsoft.com/library/?url=/library/en-us/dnsql2k/html/ufairs.asp?frame=true#ufairs_topic3

“Custom Dataset Data Extension for Microsoft Reporting Services”— 我为支持根据 ADO.NET 数据集报告而开发的自定义数据扩展。 www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=B8468707-56EF-4864-AC51-D83FC3273FE5

Download 411TEO.ZIP

有关 Hardcore Visual Basic 和 Pinnacle Publishing 的详细信息,请访问它们的位于 http://www.pinpub.com/ 的 Web 站点。

注:这不是 Microsoft Corporation 的 Web 站点。Microsoft 对它的内容不承担责任。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐