zoukankan      html  css  js  c++  java
  • 详解Silverlight访问SQL数据库【附示例源码下载】(转)

    我们要实现, 用户输入用户名和密码后,点击登录按钮,传递用户名和密码到服务器端, 通过WCF访问MSSQL数据库,调用存储过程,在服务器端对用户名和密码进行匹配,匹配成功,则返回登录成功,否则,则是失败。【示例源码下载

    在文章开始前,我们需要做一下准备工作,

    • 开发环境需求: VS2008 SP1, Silverlight 3 Develop Tools for VS2008 SP1, 客户端Silverlight 3 Runtime, MSSQL 2005 SP3 ;
    • 建立例程数据库 SilverlightDemo,在数据库中建立一个新表 Users,包含以下字段;

     

    添加内容到Users表,为了方便起见,密码全部使用明文,在正式项目中,建议对密码字段进行加密使用。

     

    这里,我们验证用户名和密码,有两种简单方式,

    一是使用存储过程读取用户名和密码,然后在服务器端进行用户名和密码匹配校验,如果查找到匹配数据,则返回登录成功,否则,则是登录失败;

    二是传用户名和密码到存储过程中,在数据库存储过程中进行判断,使用Select语句进行查找,对应用户名和密码,如果查找到匹配结果,则返回用户ID, 服务器端接收到用户ID,则返回登录成功,否则,则是失败;

    在本例中,主要是对Silverlight访问数据库进行讲述,所以,对于验证方法,不进行详细描述和讲解,如果有问题,可以留言给我,我们继续讨论,这里,我将使用第一种验证方法。 为此,建立一个简单的存储过程:

    1. CREATE PROCEDURE [dbo].[Login] 
    2. ( @UserName Varchar(30)) 
    3. AS 
    4.      
    5.        Select cUserName, cPassword 
    6.        From Users 
    7.        Where cUserName = @UserName 
    8.     RETURN 
    9. SET NOCOUNT ON 

    在完成上面的准备工作后,开始建立新的Silverlight项目,

    1. 建立一个新项目"SilverlightDBDemo",

    2. 在MainPage中建立简单的登录界面,如下

    3. 在Web项目中添加新选项

    4. 添加一个简单的用户信息类Users,作为WCF的契约成员,当我们从数据库中读取信息后,将赋值给该类的契约成员,方便客户端进行调用;

    VS2008将自动生成Users类代码,在类命名前添加数据契约属性[DataContract()]。 为了能够使绑定数据返回修改通知,这里需要继承INotifyPropertyChanged接口,该步骤不添加对本教程也没有影响,为了以后例程代码完整性,这里我继承了该接口。在接口上点击右键,生成代码。

    代码如下:

    1. namespace SilverlightDBDemo.Web 
    2.     [DataContract()] 
    3.     public class Users : INotifyPropertyChanged 
    4.     { 
    5.         #region INotifyPropertyChanged Members 
    6.         public event PropertyChangedEventHandler PropertyChanged; 
    7.         #endregion 
    8.     } 

    5. 在Users类中,添加契约成员

    1. private string userName; 
    2. [DataMember()] 
    3. public string UserName 
    4.     get { return userName; } 
    5.     set { userName = value;} 
    6. private string password; 
    7. [DataMember()] 
    8. public string Password 
    9.     get { return password;  } 
    10.     set { password = value; } 

    6. 建立构造函数 public Users(string sUserName,string sPassword),传递用户名和密码给契约成员;

    1. using System; 
    2. using System.ComponentModel; 
    3. using System.Runtime.Serialization; 
    4. namespace SilverlightDBDemo.Web 
    5.     [DataContract()] 
    6.     public class Users : INotifyPropertyChanged 
    7.     { 
    8.         private string userName; 
    9.         [DataMember()] 
    10.         public string UserName 
    11.         { 
    12.             get { return userName; } 
    13.             set { userName = value;} 
    14.         } 
    15.         private string password; 
    16.         [DataMember()] 
    17.         public string Password 
    18.         { 
    19.             get { return password;  } 
    20.             set { password = value; } 
    21.         } 
    22.         public Users(string sUserName,string sPassword) 
    23.         { 
    24.             UserName = sUserName; 
    25.             Password = sPassword; 
    26.         } 
    27.         #region INotifyPropertyChanged Members 
    28.         public event PropertyChangedEventHandler PropertyChanged; 
    29.         #endregion 
    30.     } 

    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文件,可以看到以下代码:

    1. using System; 
    2. using System.Linq; 
    3. using System.Runtime.Serialization; 
    4. using System.ServiceModel; 
    5. using System.ServiceModel.Activation; 
    6. using System.Collections.Generic; 
    7. using System.Text; 
    8. namespace SilverlightDBDemo.Web 
    9.     [ServiceContract(Namespace = "")] 
    10.     [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    11.     public class DBService 
    12.     { 
    13.         [OperationContract] 
    14.         public void DoWork() 
    15.         { 
    16.             // Add your operation implementation here 
    17.             return
    18.         } 
    19.         // Add more operations here and mark them with [OperationContract] 
    20.     } 

    这里我们没有修改ServiceContract命名空间,所以保持默认为空,AspNet的兼容需求模式我们保持默认。在正式项目中,我们习惯将所有的[OperationContract]函数放入一个接口文件中,这样方便扩展以及维护,在本例,为了方便大家理解,就不把[OperationContract]放入接口文件。 在VS2008自动生成代码下面直接添加数据库访问代码。

    10. 在添加服务器端数据库访问代码前,需要修改Web.Config文件。和Asp.Net项目一样,在链接数据库前,我们首先需要在Web.Config中配置数据库连接字符串,请自行替换数据库登录ID和密码

    1. <appSettings> 
    2. <add key="DbServiceConnectionString" value="Data Source=(Local);Initial Catalog=SilverlightDemo;User Id=dev;Password=dev;"/> 
    3. </appSettings> 

    11. 前文已经说过,Silverlight仅支持使用BasicHttpBinding通过WCF service进行通讯,而VS2008自动生成的代码是customBinding,所以,我们也需要在Web.Config中进行修改.下面是VS2008自动生成的Web.Config部分代码,划线部分是下面要修改的部分。

    1. <system.serviceModel> 
    2.   <behaviors> 
    3.    <serviceBehaviors> 
    4.     <behavior name="SilverlightDBDemo.Web.DBServiceBehavior"> 
    5.      <serviceMetadata httpGetEnabled="true" /> 
    6.      <serviceDebug includeExceptionDetailInFaults="False" /> 
    7.     </behavior> 
    8.    </serviceBehaviors> 
    9.   </behaviors> 
    10.   <bindings> 
    11.    <customBinding> 
    12.     <binding name="customBinding0"> 
    13.      <binaryMessageEncoding /> 
    14.      <httpTransport /> 
    15.     </binding> 
    16.    </customBinding> 
    17.   </bindings> 
    18.   <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
    19.   <services> 
    20.    <service behaviorConfiguration="SilverlightDBDemo.Web.DBServiceBehavior" 
    21.     name="SilverlightDBDemo.Web.DBService"> 
    22.     <endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" 
    23.      contract="SilverlightDBDemo.Web.DBService" /> 
    24.     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    25.    </service> 
    26.   </services> 
    27. </system.serviceModel> 

    这里我们需要修改以下几个地方:

    首先删除customBinding,从上面代码,第10行,到17行,使用下面代码替换:

    1. <bindings> 
    2.   <basicHttpBinding> 
    3.     <binding name="BasicHttpBinding_IDataService" 
    4.         maxBufferPoolSize="2147483647" 
    5.         maxReceivedMessageSize="2147483647" 
    6.         maxBufferSize="2147483647"> 
    7.       <readerQuotas 
    8.           maxArrayLength="2147483647" 
    9.           maxBytesPerRead="2147483647" 
    10.           maxDepth="2147483647" 
    11.           maxNameTableCharCount="2147483647" 
    12.           maxStringContentLength="2147483647" /> 
    13.     </binding> 
    14.   </basicHttpBinding> 
    15. </bindings> 

    其中那些2147483647之类的属性可以删除,但是如果读取数据库中的大型表格,就需要设置缓冲池之类的尺寸了。这里,我们已经使用了basicHttpBinding. Binding name我使用了BasicHttpBinding_DBService,大家可以随意更换,下面将用到。

    然后修改22行和23行的代码,将endpoint中的binding,内容修改为basicHttpBinding,bindingConfiguration的内容修改为BasicHttpBinding_DBService。

    1. <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_DBService" contract="SilverlightDBDemo.Web.DBService" /> 

    12. 现在我们可以在DBService.svc.cs中添加存取数据库代码,对用户名和密码进行简单匹配,这里不再着重讲述如何条件匹配登录信息。这里演示了如何调用数据库存储过程。完成存取数据库代码后,成功编译Web项目。代码有点长,这里折叠起来。

    1. private string connectionString = WebConfigurationManager.AppSettings["DbServiceConnectionString"]; 
    2. [OperationContract] 
    3. public bool GetUser(string cUserName, string cPassword) 
    4.     SqlConnection conn = new SqlConnection(connectionString); 
    5.     SqlCommand cmd = new SqlCommand("Login", conn); 
    6.     cmd.CommandType = CommandType.StoredProcedure; 
    7.     cmd.Parameters.AddWithValue("@UserName", cUserName); 
    8.     try 
    9.     { 
    10.         conn.Open(); 
    11.         SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow); 
    12.         if (reader.Read()) 
    13.         { 
    14.             Users user = new Users((string)reader["cUserName"], 
    15.                 (string)reader["cPassword"]); 
    16.             if (user.Password == cPassword) 
    17.             { 
    18.                 return true
    19.             } 
    20.             else 
    21.             { 
    22.                 return false
    23.             } 
    24.         } 
    25.         else 
    26.         { 
    27.             return false
    28.         } 
    29.     } 
    30.     finally 
    31.     { 
    32.         conn.Close(); 
    33.     } 
    34. }  

    13. 在SilverlightDBDemo客户端,点击右键添加服务引用

    14. 在弹出窗口中,点击"Discover",查找本地WCF service。在地址栏会自动搜索到本地的Service引用,在Services树形框中我们可以看到,在服务器端建立的DBService.svc,双击打开,可以看到,我们建立的GetUser函数,以及默认的DoWork函数。修改下面的命名空间为"DBService",方便调用。

    15. 点击"Advanced.."高级按钮,确认选中"Reuse types in referenced assembiles",如下图,

    16. 然后,点击确定,会在客户端中生成DBService服务引用。

    17. 在生成DBService服务引用后,VS2008会自动生成一个ServiceReferences.ClientConfig文件。

    我们需要留意查看一下该文件内容。其中,bindings信息是basicHttpBinding,而endpoint内容和Web.Config中的内容相同。这里我们不需要修改任何代码。

    1. <configuration> 
    2.     <system.serviceModel> 
    3.         <bindings> 
    4.             <basicHttpBinding> 
    5.                 <binding name="BasicHttpBinding_DBService" maxBufferSize="2147483647" 
    6.                     maxReceivedMessageSize="2147483647"> 
    7.                     <security mode="None"> 
    8.                         <transport> 
    9.                             <extendedProtectionPolicy policyEnforcement="Never" /> 
    10.                         </transport> 
    11.                     </security> 
    12.                 </binding> 
    13.             </basicHttpBinding> 
    14.         </bindings> 
    15.         <client> 
    16.             <endpoint address="http://localhost/SilverlightDBDemo.Web/DBService.svc" 
    17.                 binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_DBService" 
    18.                 contract="DBService.DBService" name="BasicHttpBinding_DBService" /> 
    19.         </client> 
    20.     </system.serviceModel> 
    21. </configuration> 

    18. 下面我们将在客户端调用该服务引用,获取数据库的返回值,根据返回值,我们将简单判断登录是否成功。

    进入MainPage.xaml.cs中,建立GetUser方法。该代码中EndpointAddress是最重要的,出现没有发现远程服务器错误,和这里设置也有关系。在client_GetUserCompleted中,e.Result代表了数据库返回值。可以接受任何值,大家可以根据需要进行值类型转换。每次,用户点击登陆按钮,Silverlight客户端都会向服务器端请求验证,返回结果会在提示信息栏显示。

    1. private void GetUser() 
    2.     EndpointAddress address = new EndpointAddress(new Uri(Application.Current.Host.Source, "/SilverlightDBDemo.Web/DBService.svc")); 
    3.     DBServiceClient client = new DBServiceClient(new BasicHttpBinding(), address); 
    4.     client.GetUserCompleted += client_GetUserCompleted; 
    5.     client.GetUserAsync(txtUsername.Text, pbPassword.Password); 
    6. private void client_GetUserCompleted(object sender, GetUserCompletedEventArgs e) 
    7.     try 
    8.     { 
    9.         if (e.Result) 
    10.         { 
    11.             tbMessage.Text = "登录成功!"
    12.         } 
    13.         else 
    14.         { 
    15.             tbMessage.Text = "登录失败!"
    16.         } 
    17.     } 
    18.     catch (Exception error) 
    19.     { 
    20.         tbMessage.Text = error.ToString(); 
    21.     } 
    22. private void btLogin_Click(object sender, RoutedEventArgs e) 
    23.     GetUser(); 

    登录成功如下图:

    来自:http://www.aspxcs.net/HTML/Silverlight/List_9.html http://www.aspxcs.net/HTML/Silverlight/List_9_11.html

  • 相关阅读:
    ajax实现异步请求的过程
    GET和POST的区别,何时使用POST?
    函数有几种调用方式?
    substring、slice、substr的区别
    Spring 调用 Stored Procedure 并获取返回值
    Oracle 中, 使用 Instr 函数 替换 OR
    Oracle Materialized View refresh
    Oracle中Union 和 Union All
    toString() 和 强制类型转换 (String)
    2013年这一年
  • 原文地址:https://www.cnblogs.com/Godblessyou/p/2019850.html
Copyright © 2011-2022 走看看