zoukankan      html  css  js  c++  java
  • 稳扎稳打Silverlight(56) 4.0通信之与 WCF Data Services 进行通信

    [索引页]
    [源码下载]


    稳扎稳打Silverlight(56) - 4.0通信之与 WCF Data Services 进行通信



    作者:webabcd


    介绍
    Silverlight 4.0 对 WCF Data Services 的支持:

    • DataServiceCollection<T> - 继承自 ObservableCollection<T>,用于将 WCF Data Services 提供的数据绑定到 Silverlight 控件上,当数据发生变化时可提供通知



    在线DEMO
    http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html


    示例
    演示 Silverlight 4.0 与 WCF Data Services 之间的通信
    1、服务端
    MyWCFDataService.svc.cs

    代码
    /*
     * WCF Data Services - 用于提供基于 OData 协议的数据服务
     * OData 协议 - 开放数据协议(Open Data Protocol),其基于 REST-ful 协议,参考:
    http://www.odata.org/
     
    */

    using System;
    using System.Collections.Generic;
    using System.Data.Services;
    using System.Data.Services.Common;
    using System.Linq;
    using System.ServiceModel.Web;
    using System.Web;

    namespace Silverlight40.Web.Service
    {
        
    public class MyWCFDataService : DataService<Model.NorthwindEntities>
        {
            
    public static void InitializeService(DataServiceConfiguration config)
            {
                config.SetEntitySetAccessRule(
    "*", EntitySetRights.All);

                
    // 指定对 Products, Categories, Orders 启用服务端分页,页大小为 3
                config.SetEntitySetPageSize("Products"3);
                config.SetEntitySetPageSize(
    "Categories"3);
                config.SetEntitySetPageSize(
    "Orders"3);

                config.DataServiceBehavior.MaxProtocolVersion 
    = DataServiceProtocolVersion.V2;
            }
        }
    }



    2、客户端
    Demo.xaml

    代码
    <navigation:Page x:Class="Silverlight40.WCFDataServices.Demo" 
               xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
               xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008"
               xmlns:mc
    ="http://schemas.openxmlformats.org/markup-compatibility/2006"
               xmlns:navigation
    ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
               xmlns:sdk
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
               Title
    ="Demo Page">
        
    <Grid x:Name="LayoutRoot">
            
    <StackPanel Orientation="Vertical" HorizontalAlignment="Left">

                
    <!--
                        用于演示通过 WCF Data Services 实现数据的增删改查
                    
    -->
                
    <StackPanel Orientation="Horizontal">
                    
    <Button Name="btnGetData" Content="获取数据" Margin="5" Click="btnGetData_Click" />
                
    </StackPanel>

                
    <TextBlock Text="产品类别列表:" Margin="5" />
                
    <sdk:DataGrid Name="gridCategory" Margin="5" Height="200" Width="400" AutoGenerateColumns="False" ItemsSource="{Binding}" 
                           SelectionChanged
    ="gridCategory_SelectionChanged">
                    
    <sdk:DataGrid.Columns>
                        
    <sdk:DataGridTextColumn Header="类别ID" Binding="{Binding CategoryID}" IsReadOnly="True" />
                        
    <sdk:DataGridTextColumn Header="类别名称" Binding="{Binding CategoryName}" />
                    
    </sdk:DataGrid.Columns>
                
    </sdk:DataGrid>

                
    <TextBlock Text="产品列表:" Margin="5" />
                
    <sdk:DataGrid Name="gridProduct" Margin="5" Height="200" Width="400" AutoGenerateColumns="False" ItemsSource="{Binding}" >
                    
    <sdk:DataGrid.Columns>
                        
    <sdk:DataGridTextColumn Header="产品ID" Binding="{Binding ProductID}" IsReadOnly="True" />
                        
    <sdk:DataGridTextColumn Header="产品名称" Binding="{Binding ProductName}" />
                        
    <sdk:DataGridTextColumn Header="单价" Binding="{Binding UnitPrice}" IsReadOnly="True" />
                    
    </sdk:DataGrid.Columns>
                
    </sdk:DataGrid>

                
    <Button Name="btnSave" Content="保存" Margin="5" Width="400" Click="btnSave_Click" />



                
    <!--
                        用于演示 WCF Data Services 的服务端分页
                    
    -->
                
    <TextBlock Text="订单列表:" Margin="5,20,5,5" />
                
    <sdk:DataGrid Name="gridOrder" Margin="5" Height="200" Width="400" IsReadOnly="True" AutoGenerateColumns="False" ItemsSource="{Binding}" >
                    
    <sdk:DataGrid.Columns>
                        
    <sdk:DataGridTextColumn Header="订单ID" Binding="{Binding OrderID}" />
                        
    <sdk:DataGridTextColumn Header="客户ID" Binding="{Binding CustomerID}" />
                    
    </sdk:DataGrid.Columns>
                
    </sdk:DataGrid>
                
    <TextBlock Name="txtCurrentPageIndex" />
                
    <Button Name="btnPrev" Content="上一页" Margin="5" Width="400" />
                
    <Button Name="btnNext" Content="下一页" Margin="5" Width="400" />

            
    </StackPanel>
        
    </Grid>
    </navigation:Page>


    Demo.xaml.cs

    代码
    /*
     * 演示 Silverlight 4.0 与 WCF Data Services 之间的通信
     * 
     * DataServiceCollection<T> - 继承自 ObservableCollection<T>。用于将 WCF Data Services 提供的数据绑定到 Silverlight 控件上,当数据发生变化时可提供通知
     *     LoadAsync(IQueryable<T>) - 从数据服务上异步加载 IQueryable<T> 数据到 DataServiceCollection<T> 中(在 LoadCompleted 触发之前不能再调用此方法)
     *     LoadAsync() - 当 DataServiceCollection<T> 表示为某实体的导航属性时,从数据服务上异步加载该数据(在 LoadCompleted 触发之前不能再调用此方法)
     *     LoadCompleted - 异步加载完成后所触发的事件
     *         LoadCompletedEventArgs - LoadCompleted 事件的事件参数
     *         LoadCompletedEventArgs.QueryOperationResponse - 获取数据服务对改查询操作的响应
     *             QueryOperationResponse.Error - 引发的异常
     *             QueryOperationResponse.Headers -  HTTP 的响应头
     *             QueryOperationResponse.Query - 对应的 DataServiceQuery(DataServiceQuery.RequestUri - 请求数据服务的 URI) 对象
     *             QueryOperationResponse.StatusCode - HTTP 的响应代码
     *     Continuation - 返回一个 DataServiceQueryContinuation<T> 对象,该对象封装了当前查询结果的下一页的 URI
     *         DataServiceQueryContinuation<T>.NextLinkUri - 当前查询结果的下一页的 URI
     *     LoadNextPartialSetAsync() - 加载下一页数据到 DataServiceCollection<T> 中
     * 
     * Silverlight 通过 ObservableCollection<T> 与 ADO.NET Data Services 1.0 进行通信详见 
    http://www.cnblogs.com/webabcd/archive/2009/03/12/1409281.html
     * WCF Data Services(ADO.NET Data Services 1.5)新特性详见 
    http://www.cnblogs.com/webabcd/archive/2010/06/11/1756071.html
     
    */

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Navigation;

    using Silverlight40.MyWCFDataServiceReference;
    using System.Data.Services.Client;

    namespace Silverlight40.WCFDataServices
    {
        
    public partial class Demo : Page
        {
            
    private NorthwindEntities _context;
            
    private DataServiceCollection<Category> _categories;

            
    public Demo()
            {
                InitializeComponent();
            }

            
    protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                
    // 指定数据服务地址
                _context = new NorthwindEntities(new Uri("Service/MyWCFDataService.svc", UriKind.Relative));

                _categories 
    = new DataServiceCollection<Category>();
                _categories.LoadCompleted 
    += new EventHandler<LoadCompletedEventArgs>(_categories_LoadCompleted);

                
    // 演示如何通过 WCF Data Services 做服务端分页
                ServerPagingDemo();
            }

            
    // 开始异步加载 Categories 数据
            private void btnGetData_Click(object sender, RoutedEventArgs e)
            {
                gridCategory.DataContext 
    = null;
                gridProduct.DataContext 
    = null;

                
    // 加载 Categories 表中的全部数据
                var query = from c in _context.Categories select c;
                _categories.LoadAsync(query);

                btnGetData.IsEnabled 
    = false;
            }

            
    // 异步加载 Categories 数据完成
            void _categories_LoadCompleted(object sender, LoadCompletedEventArgs e)
            {
                
    if (e.Error == null)
                {
                    
    if (_categories.Continuation != null)
                    {
                        
    // 在数据服务中 Categories 被服务端分页了,所以需要不断调用 LoadNextPartialSetAsync() ,以便加载全部的 Categories 数据
                        _categories.LoadNextPartialSetAsync();
                    }
                    
    else
                    {
                        gridCategory.DataContext 
    = _categories;
                        gridCategory.SelectedIndex 
    = 0;

                        btnGetData.IsEnabled 
    = true;
                    }
                }
                
    else
                {
                    MessageBox.Show(e.Error.ToString());
                    btnGetData.IsEnabled 
    = true;
                }
            }

            
    // 开始异步加载指定 Category 下的 Products 数据
            private void gridCategory_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                Category category 
    = gridCategory.SelectedItem as Category;

                
    if (category != null)
                {
                    
    if (category.Products.Count == 0)
                    {
                        category.Products.LoadCompleted 
    += new EventHandler<LoadCompletedEventArgs>(Products_LoadCompleted);

                        
    try
                        {
                            
    // 加载实体的导航属性数据
                            category.Products.LoadAsync();
                        }
                        
    catch (InvalidOperationException ex)
                        {
                            MessageBox.Show(ex.ToString());
                        }
                    }
                    
    else
                    {
                        gridProduct.DataContext 
    = category.Products;
                    }
                }
            }

            
    // 异步加载 Products 数据完成
            void Products_LoadCompleted(object sender, LoadCompletedEventArgs e)
            {
                
    if (e.Error == null)
                {
                    DataServiceCollection
    <Product> products = sender as DataServiceCollection<Product>;

                    
    if (products.Continuation != null)
                    {
                        
    try
                        {
                            products.LoadNextPartialSetAsync();
                        }
                        
    catch (InvalidOperationException ex)
                        {
                            MessageBox.Show(ex.ToString());
                        }
                    }
                    
    else
                    {
                        gridProduct.DataContext 
    = products;
                    }
                }
                
    else
                {
                    MessageBox.Show(e.Error.ToString());
                }
            }

            
    // 异步保存 Categories 中的被更新的数据(包括增删改),由于 Products 是 Category 的导航属性,所以相关的 Products 的数据的更新也会被保存
            private void btnSave_Click(object sender, RoutedEventArgs e)
            {
                
    try
                {
                    
    /*
                     * NorthwindEntities - 继承自 DataServiceContext,在 VS 中引用服务后会自动生成这个对象
                     *     DataServiceContext.BeginSaveChanges() - 将有变化的数据提交至数据服务端进行更新
                     *     DataServiceContext.EndSaveChanges() - 获取 BeginSaveChanges() 操作的结果,返回一个 DataServiceResponse 类型的对象
                     
    */

                    _context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, 
    null);
                }
                
    catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

            
    // 数据被异步保存后
            private void OnChangesSaved(IAsyncResult result)
            {
                
    bool error = false;

                
    this.Dispatcher.BeginInvoke(() =>
                {
                    
    try
                    {
                        DataServiceResponse response 
    = _context.EndSaveChanges(result);

                        
    foreach (ChangeOperationResponse changeResponse in response)
                        {
                            
    if (changeResponse.Error != null)
                                error 
    = true;
                        }

                        
    if (!error)
                        {
                            MessageBox.Show(
    "数据更新成功");
                        }
                        
    else
                        {
                            MessageBox.Show(
    "数据更新失败");
                        }
                    }
                    
    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                });
            }



            
    private int _pageIndex = 0;
            
    private int _pageSize = 3;

            
    // 演示如何通过 WCF Data Services 做服务端分页
            private void ServerPagingDemo()
            {
                BindOrder();

                btnNext.Click 
    += (s, args) =>
                {
                    _pageIndex
    ++;
                    BindOrder();
                };

                btnPrev.Click 
    += (s, args) =>
                {
                    _pageIndex
    --;
                    BindOrder();
                };
            }

            
    private void BindOrder()
            {
                txtCurrentPageIndex.Text 
    = "当前页索引:" + _pageIndex.ToString();

                var query 
    = from o in _context.Orders select o;
                query 
    = query.Skip(_pageIndex * _pageSize).Take(_pageSize);
                DataServiceCollection
    <Order> orders = new DataServiceCollection<Order>();
                orders.LoadAsync(query);

                orders.LoadCompleted 
    += (s, args) =>
                {
                    gridOrder.DataContext 
    = orders;
                };
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    Docker虚拟机配置手札(centos)
    Nginx配置手札
    登录的顶号功能实现
    苹果登录服务端JWT算法验证-PHP
    mac Read-Only filesystem (转载)
    ssh公私钥登录/git公私钥认证
    crontab 定时访问指定url,定时脚本
    网站通用 敏感词列表
    游戏行业术语一览(2)--游戏运营转化率[转载]
    <转载>为什么VR不可能成功?
  • 原文地址:https://www.cnblogs.com/webabcd/p/1847567.html
Copyright © 2011-2022 走看看