zoukankan      html  css  js  c++  java
  • 图文详解Silverlight访问MSSQL数据库

    银光中国网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访问数据库进行讲述,所以,对于验证方法,不进行详细描述和讲解,如果有问题,可以留言给我,我们继续讨论,这里,我将使用第一种验证方法。 为此,建立一个简单的存储过程:

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

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

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

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

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

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

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

    代码如下:

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

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

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

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

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

    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 
     9 namespace SilverlightDBDemo.Web
    10 {
    11     [ServiceContract(Namespace = "")]
    12     [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    13     public class DBService
    14     {
    15         [OperationContract]
    16         public void DoWork()
    17         {
    18             // Add your operation implementation here
    19             return;
    20         }
    21 
    22         // Add more operations here and mark them with [OperationContract]
    23     }
    24 }

    这里我们没有修改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"
    2      contract="SilverlightDBDemo.Web.DBService" />

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

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

    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>
    22 

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

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

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

    登录成功如下图:

    到这里为止,我想你已经学会了如何使用WCF存取MSSQL数据库了。如果有问题,可以留言给我,或者到Silverlight开发QQ群100844510来讨论。

    代码下载

    本文为原创文章,第一次发布在 银光中国网(SilverlightChina.Net)

    如需转载,请注明出处,谢谢。

  • 相关阅读:
    前端 HTML CSS
    前端部分1:HTML
    异常处理专区:
    IO模型介绍
    协程专区
    线程专区
    操作系统简介专区
    进程专区
    正则表达式专区:
    题解 P2158 【[SDOI2008]仪仗队】
  • 原文地址:https://www.cnblogs.com/jv9/p/1635655.html
Copyright © 2011-2022 走看看