1. 引言»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Crystal Report已内嵌为微软 Visual Studio .NET的标准报表工具,它的优点是:在 .NET 平台上能够轻松创建交互式的、高质量显现的报表内容;可以在 Web 平台和 Windows 平台上承载报表,并将 Crystal Report作为报表的 Web 服务在 Web 服务器上发布;利用Crystal Report 创建的Web应用程序,使用户可以深化图表并根据需要筛选信息。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
本文简单介绍了在ASP.NET 中,如何利用WebService来实现Crystal Report与数据库的连接。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Web Service是基于通过网络支持计算机间的集成来设计的软件应用程序。它的接口用计算机可处理的格式(通常是WSDL)来描述。其他软件应用程序通过该接口描述的方式与Web 服务交流,利用SOAP 消息,通常是序列化的XML 通过 HTTP 或其它网络标准传输。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
2. SQL Server准备工作
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
首先建立一个表,并创建一个存储过程和视图,存储过程将被WebService里的WebMethod调用,视图将方便数据集(.XSD)的创建。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
2.1 与存储过程相比SQL语句方式有以下好处:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
① 预编译,已优化,效率较高;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
② 可以有效的防止SQL注入式攻击;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
③ 可以接受输入参数;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
④ 修改方便。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
2.2 建立视图的好处是:
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
在创建数据集(XSD)时不用一个一个地加元素、指定数据类型,直接拖入已建好的视图即可。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
3. 创建一个WebService项目
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
3.1调用EnterpriseLibrary»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
EnterpriseLibrary是可重用的程序块库,用于解决共性的企业级开发过程中所面临的挑战:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
① 较低风险(经过实践验证的、精准的)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
② 降低成本(可充用)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
③ 快速实施的问题(易用)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
④ 扩展性»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
⑤ 一致性»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
正是因为它强调了一致性、扩展性、易用性和集成性问题,减少了代码的输入,并且可免费下载。因此我们选用了EnterpriseLibrary。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
        在references里引用下面的几个EnterpriseLibrary,后面创建WebService时将直接使用它:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Microsoft.Practices.EnterpriseLibrary.Data;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Microsoft.Practices.EnterpriseLibrary.Configuration;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
3.2 配置Config
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Config有以下优点:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
①  ASP.NET允许配置内容可以和静态内容、动态页面和商业对象放置在同一应用的目录结构下。当管理人员需要安装新的ASP.NET应用时,只需要将应用目录拷贝到新的机器上即可。  »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
②   ASP.NET的配置内容以纯文本方式保存,可以以任意标准的文本编辑器、XML解析器和脚本语言解释、修改配置内容。  »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
③   ASP.NET 提供了扩展配置内容的架构,以支持第三方开发者配置自己的内容。  »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
④  ASP.NET配置文件的更新被系统自动监控,无须管理人员手工干预。              因此将与数据库连接的相关信息写在Configuration里面,有明显的优势:易于部署;易于以编程方式访问;支持动态更新。  »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
3.3 建立WebService
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Web Servcie最主要的优点是,使用不同程序和在不同系统平台上开发出来的程序,都可以相互通信。另外它还可以跨防火墙地通信,集成了应用程序,集成了B2B,可重用软件和数据等等。下面是WebService 主要代码:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
PersonMain.asmx:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
[WebMethod]»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
public DataSet PersonMain(DateTime birthday_from,DateTime birthday_to)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
// Create the Database object, using the default database service. »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
// The default database service is determined through configuration.»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Database db = DatabaseFactory.CreateDatabase();»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
string Command = "Person_Procedure";    »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
//The Person_Procedure is the name of procedure.»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
DBCommandWrapper dbCommandWrapper = db.GetStoredProcCommandWrapper(Command);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
dbCommandWrapper.AddInParameter("birthday_from",DbType.DateTime,birthday_from);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
dbCommandWrapper.AddInParameter("birthday_to",DbType.DateTime,birthday_to);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
//Bothe @birthday_from and @birthday_to are the parameter of procedure.    »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
DataSet ds = null;              »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
ds= db.ExecuteDataSet(dbCommandWrapper);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
// Note: connection was closed by ExecuteDataSet method call»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
//return productsDataSet;      »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
return ds;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
}»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    在实际工作中,为了在调用时能一目了然地知道它的功能,通常将[WebMethod]加上简单的描述语句,格式如:[ WebMethod ( Description = "Your description information about this WebMethod" ) ]»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
4. 创建一个WebApplication项目
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
4.1引用»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
① 首先在references里加上下面的几个CrystalReport相关的引用,因为后面的CrystalReport要用到它们:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
CrystalDecisions.CrystalReports.Engine;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
CrystalDecisions.Shared;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
CrystalDecisions.ReportSource;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
② 在Web References里加上刚才在WebService里创建的PersonMain.asmx,并取名为PersonMain。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
4.2 数据集(.xsd)和CrystalReport(.rpt)
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
① Web  Service平台是用XSD来作为数据类型系统的。当我们用某种语言如VB.NET或C#来构造一个Web  Service时,为了符合Web  Service标准,所有我们使用的数据类型都必须被转换为XSD类型。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
新建一个数据集PersonDS.xsd,从服务器资源管理器中把我们已做好的视图拖进来。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
② 新建一个CrystalReport:Person.rpt。把刚才新建的数据集PersonDS.xsd加进来,将字段拖入报表中相应的位置。如果有多个视图,要通过相关字段将它们连接起来,同时要保证有且仅有一个出发点,最终不能有孤立点,而且不能有回路。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
4.3 数据加载
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
① 在WebApplication项目里加一个类,它的作用是把数据集加到报表中去,下面的数据加载类将调用它。在实际工作中,我们通常将它和其它一些通用的方法放在一起做成.dll,方便调用。下面是这个类的主要代码:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
DBTable.cs:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
public void addTableforReportDataSet(DataSet srcds,string dtname,DataSet rpds)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
{»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
if(srcds != null)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
{»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
if(srcds.Tables.Count > 0)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
{»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
  if(srcds.Tables[0].Rows.Count > 0)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
  {»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    foreach(DataRow copyRow in srcds.Tables[0].Rows)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
{              »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
rpds.Tables[dtname].ImportRow(copyRow);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    }»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    }»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
  }»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
}    »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
}»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
② 新建一个数据加载类,主要代码如下:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
PersonLoadData.cs:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
public ReportDocument generateReport(DateTime birthday_from,DateTime birthday_to)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
{»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
      WebApplication.Person.PersonDS reportDS = new PersonDS();  WebApplication.PersonMain.PersonMain webServer = new                PersonMain.PersonMain();    »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
DBTable dbt = new DBTable();    »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    DataSet ds =webServer.PersonWS(birthday_from,birthday_to);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    dbt.addTableforReportDataSet(ds,"Person",reportDS);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    ReportDocument oRpt = new ReportDocument();»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
oRpt.Load(@"c:\inetpub\wwwroot\WebApplication\Person\Person.rpt");»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    oRpt.SetDataSource(reportDS);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    return oRpt;»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
上面加载报表用的是绝对路径(加下划线),但在实际应用中我们普遍用的是相对路径,即:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
string rpLoc = AppDomain.CurrentDomain.BaseDirectory +@"\Rp\Rp00076\Rp00076.rpt";»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
oRpt.Load(rpLoc); »êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
4.4 数据显示
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
为显示数据是否被调用,我们可以新建一个Web页,在上面放入二个textbox用来传参,一个CrystalReportViewer用来显示CrystalReport,一个确定按钮。主要代码如下:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
BeginPage.aspx:»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
private void Button1_Click(object sender, System.EventArgs e)»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
{»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    DateTime tb1 = Convert.ToDateTime(this.TextBox1.Text);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    DateTime tb2 = Convert.ToDateTime(this.TextBox2.Text);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    WebApplication.Person.PersonLoadData testLD = new PersonLoadData();»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
    this.crView.ReportSource=testLD.generateReport(tb1,tb2);»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
}
»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
....................»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
5. 结束语»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|
Web  Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web  Service能与其他兼容的组件进行互操作。它可以使用标准的互联网协议,像超文本传输协议HTTP和XML,将功能体现在互联网和企业内部网上。Web  Service平台是一套标准,它定义了应用程序如何在Web上实现互操作性。我们可以用我们喜欢的任何语言,在我们喜欢的任何平台上写Web  Service。»êf Êc …¡!www.netcsharp.cn¸’].¬<û:|