Silverlight 2 (beta1)数据操作(4)——调用WCF进行数据CRUD操作
\n目录
\n
- 导言
\n - 软件需求
\n - 在SQL 2005中创建数据库
\n - 在Visual Studio 2008创建Silverlight工程和WCF Service
\n - 编写WCF Service
\n - 在Silverlight 2 (beta1)工程中引用WCF
\n - 在Silverlight中调用WCF进行CRUD操作
\n - 结语
\n
导言
\n
Silverlight 2支持JSON、Web Service、WCF以及Sockets等新特性对数据CRUD操作,这个系列用实例结合数据库一步一步的图文描述来学习一下Silverlight 2 beta 1中进行数据库的CRUD操作方面的实战能力。
\n
这篇文章介绍如何在Silverlight 2 beta 1中调用WCF进行数据CRUD操作。
\n
软件需求
\n
- Silverlight 2 (beta1)
\n - Visual Studio 2008
\n - SQL 2005 Express with Management Studio
\n
\n
在SQL 2005中创建数据库
\n
创建一个名为User的表,如下图所示。我在第一篇文章中详细介绍了,这一篇我们还需要这张表。
\n
\n
在Visual Studio 2008创建Silverlight工程和WCF Service
\n
第一步:在VS2008中创建一个新的Silverlight工程,命名为:YJingLee.WCF。并选择ASP.NET Web Site用来托管Silverlight应用程序。
\n
\n
第二步:在Web项目中添加一个WCF Service文件,我命名为UserService.svc
\n
\n
编写WCF Service
\n
第一步:定义服务契约。我们为WCF Service提供的增删查改方法定义服务契约。
[ServiceContract]
\npublic interface IUserService
\n{
\n [OperationContract]
\n string RetrieveUser();
\n [OperationContract]
\n bool CreateUser(string userName);
\n [OperationContract]
\n bool UpdateUser(int userID, string userName);
\n [OperationContract]
\n bool DeleteUser(int userID);
\n}
\n
第二步:在UserService中实现服务:为增删查改四个方法具体实现。这里使用SQL语句了,同第一篇类似。
public class UserService : IUserService
\n{
\n //查询用户
\n public string RetrieveUser()
\n {
\n try
\n {
\n SqlConnection _sqlConnection = new SqlConnection( ConfigurationManager.
\n ConnectionStrings["sqlConnectionString"].ConnectionString);
\n _sqlConnection.Open();
\n SqlDataAdapter da = new SqlDataAdapter();
\n da.SelectCommand = new SqlCommand(“SELECT * FROM [User]“, _sqlConnection);
\n DataSet ds = new DataSet();
\n da.Fill(ds);
\n StringBuilder sb = new StringBuilder();
\n sb.Append(“<?xml version=\\”1.0\\” encoding=\\”utf-8\\” ?>”);
\n sb.Append(“<Users>”);
\n foreach (DataRow dr in ds.Tables[0].Rows)
\n {
\n sb.Append(“<User>”);
\n sb.Append(“<UserID>”);
\n sb.Append(dr[0].ToString());
\n sb.Append(“</UserID>”);
\n sb.Append(“<UserName>”);
\n sb.Append(dr[1].ToString());
\n sb.Append(“</UserName>”);
\n sb.Append(“</User>”);
\n }
\n sb.Append(“</Users>”);
\n _sqlConnection.Close();
\n return sb.ToString();
\n }
\n catch (Exception ex)
\n {
\n return string.Empty;
\n }
\n }
\n //创建用户
\n public bool CreateUser(string userName)
\n {
\n try
\n {
\n SqlConnection _sqlConnection = new SqlConnection(ConfigurationManager.
\n ConnectionStrings["sqlConnectionString"].ConnectionString);
\n _sqlConnection.Open();
\n SqlCommand command = new SqlCommand();
\n command.Connection = _sqlConnection;
\n command.CommandType = CommandType.Text;
\n command.CommandText = “INSERT INTO [User] ([UserName]) VALUES (‘” +
\n userName.ToString().Replace(“‘”, “””) + “‘)”;
\n command.ExecuteNonQuery();
\n _sqlConnection.Close();
\n return true;
\n }
\n catch (Exception ex)
\n {
\n return false;
\n }
\n }
\n //更新用户
\n public bool UpdateUser(int userID, string userName)
\n {
\n try
\n {
\n SqlConnection _sqlConnection = new SqlConnection(ConfigurationManager.
\n ConnectionStrings["sqlConnectionString"].ConnectionString);
\n _sqlConnection.Open();
\n SqlCommand command = new SqlCommand();
\n command.Connection = _sqlConnection;
\n command.CommandType = CommandType.Text;
\n command.CommandText = “UPDATE [User] ” +
\n “SET [UserName] = ‘” + userName.ToString().Replace(“‘”, “””) + “‘” +
\n “WHERE [UserID] = ” + userID.ToString();
\n command.ExecuteNonQuery();
\n _sqlConnection.Close();
\n return true;
\n }
\n catch (Exception ex)
\n {
\n return false;
\n }
\n }
\n //删除用户
\n public bool DeleteUser(int userID)
\n {
\n try
\n {
\n SqlConnection _sqlConnection = new SqlConnection(ConfigurationManager.
\n ConnectionStrings["sqlConnectionString"].ConnectionString);
\n _sqlConnection.Open();
\n SqlCommand command = new SqlCommand();
\n command.Connection = _sqlConnection;
\n command.CommandType = CommandType.Text;
\n command.CommandText = “DELETE [User] WHERE [UserID] = ” + userID.ToString();
\n command.ExecuteNonQuery();
\n _sqlConnection.Close();
\n return true;
\n }
\n catch (Exception ex)
\n {
\n return false;
\n }
\n }
\n}
\n
第三步:修改Web.config中的服务配置。
\n
这里使用basicHttpBinding绑定,并且开启httpGetEnabled,以便后面我们可以在浏览器中查看服务。
<system.serviceModel>
\n <behaviors>
\n <serviceBehaviors>
\n <behavior name=”UserServiceBehavior”>
\n <serviceMetadata httpGetEnabled=”true”/>
\n <serviceDebug includeExceptionDetailInFaults=”false”/>
\n </behavior>
\n </serviceBehaviors>
\n </behaviors>
\n <services>
\n <service behaviorConfiguration=”UserServiceBehavior” name=”UserService”>
\n <endpoint address=”" binding=”basicHttpBinding” contract=”IUserService”>
\n </endpoint>
\n </service>
\n </services>
\n</system.serviceModel>
\n
第四步:设置Web应用程序的端口号。
\n
把器端口号设置为固定端口52600,在浏览器中查看服务是否正常:
\n
\n
好了,现在服务端我们就实现完成了。
\n
在Silverlight 2 (beta1)工程中引用WCF Service
\n
第一步:在Silverlight工程的引用节点上右击选择“Add Service Reference…”。
\n
\n
第二步:在下面的对话框中点击“Discover”按钮
\n
\n
第三步:在点击Discover按钮之后,地址栏里显示了UserService.svc。在Service面板出现一个WCF Service,双击这个服务。修改Namespace为UserService,单击OK。
\n
\n
第四步:添加完成后,在Silverlight工程的ServiceReferences.ClientConfig文件中,我们查看一下,他自动生成了WCF客户端的配置。
<configuration>
\n <system.serviceModel>
\n <bindings>
\n <basicHttpBinding>
\n <binding name=”BasicHttpBinding_IUserService” maxBufferSize=”65536″
\n maxReceivedMessageSize=”65536″>
\n <security mode=”None” />
\n </binding>
\n </basicHttpBinding>
\n </bindings>
\n <client>
\n <endpoint address=”http://localhost:52600/YJingLee.WCF_Web/UserService.svc”
\n binding=”basicHttpBinding”
\n bindingConfiguration=”BasicHttpBinding_IUserService”
\n contract=”YJingLee.WCF.UserService.IUserService”
\n name=”BasicHttpBinding_IUserService” />
\n </client>
\n </system.serviceModel>
\n</configuration>
\n
现在,我们可以在Silverlight工程中调用WCF Service了。
\n
在Silverlight中调用WCF进行CRUD操作
\n
由于在WCF服务的配置中我们采取了BasicHttpBinding,客户端也要采用BasicHttpBinding。所以我们先定义一个全局变量:
UserService.UserServiceClient userSvcClient;
\n
然后在Page()方法中,我们调用这个服务,免得每次在各个方法中调用。
userSvcClient = new YJingLee.WCF.UserService.UserServiceClient();
\n
这里,我直接这样写了,没有添加任何参数,原因很简单,在ServiceReferences.ClientConfig文件中,VS自动生成了WCF客户端的配置。当然你也可以这样写,两者选其一:
BasicHttpBinding binding = new BasicHttpBinding();
\nEndpointAddress endPoint = new EndpointAddress(
\n “http://localhost:52600/YJingLee.WCF_Web/UserService.svc”);
\nuserClient = new YJingLee.WCF.UserService.UserServiceClient(binding, endPoint);
\n
1.创建数据
\n
编写调用服务并创建数据,这里采用异步模式,我们需要注册CreateUserCompleted事件处理方法,以便完成后回调,同时调用CreateUserAsync()方法创建用户。
void createButton_Click(object sender, RoutedEventArgs e)
\n{
\n //模拟一个用户
\n string userName = “YJingLee”;
\n //注册CreateUserCompleted事件
\n userSvcClient.CreateUserCompleted += new EventHandler<YJingLee.WCF.UserService.
\n CreateUserCompletedEventArgs>(userSvcClient_CreateUserCompleted);
\n //调用CreateUserAsync()方法创建用户
\n userSvcClient.CreateUserAsync(userName);
\n}
\nvoid userSvcClient_CreateUserCompleted(object sender,
\n YJingLee.WCF.UserService.CreateUserCompletedEventArgs e)
\n{
\n //完成CreateUserAsync()方法后回调,这里象征性的提示是否完成
\n if (e.Error == null)
\n {
\n errMessage.Text = “创建用户成功!”;
\n errMessage.Visibility = Visibility.Visible;
\n }
\n else
\n {
\n errMessage.Text = e.Error.ToString();
\n errMessage.Visibility = Visibility.Visible;
\n }
\n}
\n
2.读取数据
\n
同创建数据类似,调用服务并读取数据。
void retrieveButton_Click(object sender, RoutedEventArgs e)
\n{
\n //注册RetrieveUserCompleted事件
\n userSvcClient.RetrieveUserCompleted += new EventHandler<YJingLee.WCF.UserService.
\n RetrieveUserCompletedEventArgs>(userSvcClient_RetrieveUserCompleted);
\n //调用RetrieveUserAsync()方法查询用户
\n userSvcClient.RetrieveUserAsync();
\n}
\nvoid userSvcClient_RetrieveUserCompleted(object sender,
\n YJingLee.WCF.UserService.RetrieveUserCompletedEventArgs e)
\n{
\n //调用成功,显示数据
\n if (e.Error == null)
\n displayData(e.Result);
\n}
\n
显示数据方法:
private void displayData(string xmlContent)
\n{
\n try
\n {
\n if (xmlContent != string.Empty)
\n {
\n XDocument xmlUsers = XDocument.Parse(xmlContent);
\n var users = from user in xmlUsers.Descendants(“User”)
\n select new
\n {
\n UserID = Convert.ToInt32(user.Element(“UserID”).Value),
\n UserName = (string)user.Element(“UserName”).Value
\n };
\n List<User> usersList = new List<User>();
\n foreach (var u in users)
\n {
\n User use = new User { UserID = u.UserID, UserName = u.UserName };
\n usersList.Add(use);
\n }
\n UserList.ItemsSource = usersList;
\n }
\n else
\n {
\n UserList.ItemsSource = null;
\n }
\n }
\n catch (Exception ex)
\n {\nConsole.Write(ex.Message);
\n }
\n}
\n
3.更新数据
\n
这里,我们模拟更新UserID为7的用户,修改这个用户的UserName为YJingLee。
void updateButton_Click(object sender, RoutedEventArgs e)
\n{
\n //模拟更新userID为7的用户
\n int userID = 7;
\n string userName = “YJingLee”;
\n userSvcClient.UpdateUserCompleted += new EventHandler<YJingLee.WCF.UserService.
\n UpdateUserCompletedEventArgs>(userSvcClient_UpdateUserCompleted);
\n userSvcClient.UpdateUserAsync(userID, userName);
\n}
\nvoid userSvcClient_UpdateUserCompleted(object sender,
\n YJingLee.WCF.UserService.UpdateUserCompletedEventArgs e)
\n{
\n if (e.Error == null)
\n {
\n errMessage.Text = “更新用户成功!”;
\n errMessage.Visibility = Visibility.Visible;
\n }
\n else
\n {
\n errMessage.Text = e.Error.ToString();
\n errMessage.Visibility = Visibility.Visible;
\n }
\n}
\n
4.删除数据
\n
我在这里指定UserID为7的用户。
void deleteButton_Click(object sender, RoutedEventArgs e)
\n{
\n //模拟删除userID为7的用户
\n int userID = 7;
\n userSvcClient.DeleteUserCompleted += new EventHandler<YJingLee.WCF.UserService.
\n DeleteUserCompletedEventArgs>(userSvcClient_DeleteUserCompleted);
\n userSvcClient.DeleteUserAsync(userID);
\n}
\nvoid userSvcClient_DeleteUserCompleted(object sender,
\n YJingLee.WCF.UserService.DeleteUserCompletedEventArgs e)
\n{
\n if (e.Error == null)
\n {
\n errMessage.Text = “删除用户成功!”;
\n errMessage.Visibility = Visibility.Visible;
\n }
\n else
\n {
\n errMessage.Text = e.Error.ToString();
\n errMessage.Visibility = Visibility.Visible;
\n }
\n}
\n
结语
\n
Silverlight应用程序的后端数据库操作有很多技术可以实现,像LINQ to SQL、Entity Framework、ADO.NET Data Services(Astoria )、ASP.NET Web Service(ASMX)。 这一篇使用基本的SQL语句,然后在服务层调用WCF技术实现,本来打算不写的,但是在InfoQ看到Silverlight 2.0中文学习资源集萃的推荐,我发现在数据库这块就手把这些知识掌握一下。
\n
这篇就介绍到这里。从这篇我们知道了如何在Silverlight 2 beta 1中调用WCF进行数据CRUD操作。
\n\n