wangliang 2009-12-31
本文将重点讲述Silverlight中连接MySQL数据库实例,这在RIA开发中比较基础,但是也是比较重要的内容。希望通过本文能让大家对连接MySQL有更深刻的理解。
在银光中国网(SilverlightChina.Net)有一篇"Silverlight与常用数据库互操作系列"文章,其中介绍了使用Silverlight存取不同数据库的方法和步骤。但是对于Silverlight存取MS SQL介绍的不够全面,这里我想介绍Silverlight如何通过WCF访问MSSQL数据库存储过程的。希望对大家能够有所帮助。
我们要实现, 用户输入用户名和密码后,点击登录按钮,传递用户名和密码到服务器端, 通过WCF访问MSSQL数据库,调用存储过程,在服务器端对用户名和密码进行匹配,匹配成功,则返回登录成功,否则,则是失败。
在文章开始前,我们需要做一下准备工作,
开发环境需求: VS2008 SP1, Silverlight 3 Develop Tools for VS2008 SP1, 客户端Silverlight 3 Runtime, MSSQL 2005 SP3 ;
建立例程数据库 SilverlightDemo,在数据库中建立一个新表 Users,包含以下字段;
添加内容到Users表,为了方便起见,密码全部使用明文,在正式项目中,建议对密码字段进行加密使用。
这里,我们验证用户名和密码,有两种简单方式,
一是使用存储过程读取用户名和密码,然后在服务器端进行用户名和密码匹配校验,如果查找到匹配数据,则返回登录成功,否则,则是登录失败;
二是传用户名和密码到存储过程中,在数据库存储过程中进行判断,使用Select语句进行查找,对应用户名和密码,如果查找到匹配结果,则返回用户ID, 服务器端接收到用户ID,则返回登录成功,否则,则是失败;
在本例中,主要是对Silverlight访问数据库进行讲述,所以,对于验证方法,不进行详细描述和讲解,如果有问题,可以留言给我,我们继续讨论,这里,我将使用第一种验证方法。 为此,建立一个简单的存储过程:
CREATE PROCEDURE [dbo].[Login] ( @UserName Varchar(30)) AS Select cUserName, cPassword From Users Where cUserName = @UserName RETURN SET NOCOUNT ON
在完成上面的准备工作后,开始建立新的Silverlight项目,
1. 建立一个新项目"SilverlightDBDemo",
2. 在MainPage中建立简单的登录界面,如下:
3. 在Web项目中添加新选项
4. 添加一个简单的用户信息类Users,作为WCF的契约成员,当我们从数据库中读取信息后,将赋值给该类的契约成员,方便客户端进行调用;
VS2008将自动生成Users类代码,在类命名前添加数据契约属性[DataContract()]。 为了能够使绑定数据返回修改通知,这里需要继承INotifyPropertyChanged接口,该步骤不添加对本教程也没有影响,为了以后例程代码完整性,这里我继承了该接口。在接口上点击右键,生成代码。
代码如下:
namespace SilverlightDBDemo.Web { [DataContract()] public class Users : INotifyPropertyChanged { #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion } }
5. 在Users类中,添加契约成员
private string userName; [DataMember()] public string UserName { get { return userName; } set { userName = value;} } private string password; [DataMember()] public string Password { get { return password; } set { password = value; } }
6. 建立构造函数 public Users(string sUserName,string sPassword),传递用户名和密码给契约成员;
using System; using System.ComponentModel; using System.Runtime.Serialization; namespace SilverlightDBDemo.Web { [DataContract()] public class Users : INotifyPropertyChanged { private string userName; [DataMember()] public string UserName { get { return userName; } set { userName = value;} } private string password; [DataMember()] public string Password { get { return password; } set { password = value; } } public Users(string sUserName,string sPassword) { UserName = sUserName; Password = sPassword; } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion }
7. 添加"Silverlight-enabled WCF Service",修改服务名字为 DBService.svc,需要注意的是,WCF service对于Silverlight仅支持BasicHttpBinding,而VS2008自动生成是customBinding,很多朋友说使用了"Silverlight-enabled WCF Service",链接数据库仍旧失败,无法找到远程服务器,是因为没有使用BasicHttpBinding进行通讯,造成的失败。
后文我将讲述如何修改。
8. 添加后,在Web服务器端会有DBService.svc和DBService.svc.cs文件出现,VS2008将自动更新Web项目的类库引用;
9. 双击进入DBService.svc.cs文件,可以看到以下代码:
using System; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Activation; using System.Collections.Generic; using System.Text; namespace SilverlightDBDemo.Web { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class DBService { [OperationContract] public void DoWork() { // Add your operation implementation here return; } // Add more operations here and mark them with [OperationContract] } }
这里我们没有修改ServiceContract命名空间,所以保持默认为空,AspNet的兼容需求模式我们保持默认。在正式项目中,我们习惯将所有的[OperationContract]函数放入一个接口文件中,这样方便扩展以及维护,在本例,为了方便大家理解,就不把[OperationContract]放入接口文件。 在VS2008自动生成代码下面直接添加数据库访问代码。
10. 在添加服务器端数据库访问代码前,需要修改Web.Config文件。和Asp.Net项目一样,在链接数据库前,我们首先需要在Web.Config中配置数据库连接字符串,请自行替换数据库登录ID和密码
<appSettings> <add key="DbServiceConnectionString" value="Data Source=(Local); Initial Catalog=SilverlightDemo; User Id=dev;Password=dev;"/> </appSettings>
11. 前文已经说过,Silverlight仅支持使用BasicHttpBinding通过WCF service进行通讯,而VS2008自动生成的代码是customBinding,所以,我们也需要在Web.Config中进行修改.下面是VS2008自动生成的Web.Config部分代码,划线部分是下面要修改的部分。
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="SilverlightDBDemo.Web.DBServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> <bindings> <customBinding> <binding name="customBinding0"> <binaryMessageEncoding /> <httpTransport /> </binding> </customBinding> </bindings> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> <services> <service behaviorConfiguration="SilverlightDBDemo.Web.DBServiceBehavior" name="SilverlightDBDemo.Web.DBService"> <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightDBDemo.Web.DBService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> </system.serviceModel>
-->这里我们需要修改以下几个地方:
首先删除customBinding,从上面代码,第10行,到17行,使用下面代码替换:
<bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IDataService" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"> <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" maxStringContentLength="2147483647" /> </binding> </basicHttpBinding> </bindings>
其中那些2147483647之类的属性可以删除,但是如果读取数据库中的大型表格,就需要设置缓冲池之类的尺寸了。这里,我们已经使用了basicHttpBinding. Binding name我使用了BasicHttpBinding_DBService,大家可以随意更换,下面将用到。
然后修改22行和23行的代码,将endpoint中的binding,内容修改为basicHttpBinding,bindingConfiguration的内容修改为BasicHttpBinding_DBService。