zoukankan      html  css  js  c++  java
  • MOSS 2010:Visual Studio 2010开发体验(18)——在独立的Silverlight应用程序中通过WCF访问SharePoint数据

    上一篇我讲到了如何在Silverlight中使用客户端对象模型访问SharePoint数据,诸如列表,列表条目,文档之类都是可以的,而且这个对象模型是很完整的,它既可以做数据查询,还可以做操作。简单类比一下就是,原先服务器对象模型能做的,客户端对象模型也大致能做。

    有关服务器对象模型,请参考http://www.cnblogs.com/chenxizhang/archive/2010/04/05/1704550.html

    有关客户端对象模型,请参考http://www.cnblogs.com/chenxizhang/archive/2010/04/26/1721653.html

    在上一篇中,我们是将Silverlight作为WebPart使用在SharePoint站点内部,那种做法相对简单一些,有两个好处:

    • 不需要考虑身份验证的问题(事实上,在Microsoft.SharePoint.Client.Silverlight.dll中的ClientContext,根本就不存在什么属性可以让你设置用户凭据Credentials)
    • 不需要考虑网站地址的问题。因为ClientContext有一个Current的属性,就是访问了当前的SharePoint站点的上下文引用。当然这个地址也可以明确指定。

    看起来很不错吧,但是,如果我们的Silverlight应用程序是独立运行在一个网站,那么即便我们确实修改了网站地址,例如我们的代码做了如下修改

    ClientContext ctx = new ClientContext(http://localhost:45223/sites/dev);

    但这样却仍然是无法运行的,请看下面的错误

    image

    这是什么错误呢?其实一点都不奇怪,如果你以前做过Silverlight开发,调用过外部网站的Web Service的话。这叫跨站访问控制,默认情况下,Silverlight是不可以访问外部服务的。

    关于这一点,我之前有一个文章专门介绍,请参考http://www.cnblogs.com/chenxizhang/archive/2010/03/12/1683939.html

    那好吧,我们该如何解决这个问题呢?其实很简单,我们可以在当前网站中添加一个服务,让这个服务去访问SharePoint,然后Silverlight访问该服务。这不就可以了吗?

    按照这样的思路,这一篇我准备用WCF来实现该服务,并且演示如何在Silverlight中使用它。我们的目的仍然是筛选得到年龄小于60的员工清单。

    1. 创建一个独立的Silverlight应用程序

    image

    image

    2. 对页面进行一些必要的设计

    image

    3. 创建WCF服务

    我们暂时离开Silverlight项目,切换到刚才创建项目时一起创建的一个Web项目中

    image

    在这个项目中,我们添加一个WCF服务

    image

    image

    【注意】它会增加两个文件,一个是IEmployeeService.cs(如上图所示),一个是EmployeeService.svc(如下图所示)

    image

    同时,还会修改web.config文件如下

    image

    【注意】这些属于是WCF最基本的知识,如果你对此不清楚,可以参考我有关其他的文章,例如你可以在我的博客中搜索WCF关键字

    http://www.google.com.hk/custom?domains=cnblogs.com&q=site:www.cnblogs.com/chenxizhang/+wcf&sitesearch=cnblogs.com&client=pub-4210569241504288&forid=1&channel=5875741252&ie=UTF-8&oe=UTF-8&safe=active&cof=GALT:%23008000;GL:1;DIV:%23336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:FFFFFF;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;LH:50;LW:129;L:http://www.cnblogs.com/images/logo_small.gif;S:http://www.cnblogs.com/;FORID:1&hl=zh-CN

    4. 修改该服务,使其具有一个方法,可以获取员工列表

    首先修改服务契约

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace SilverlightApplication6.Web
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IEmployeeService" in both code and config file together.
        [ServiceContract]
        public interface IEmployeeService
        {
            [OperationContract]
            void DoWork();
    
            [OperationContract]
            Employee[] GetEmployees();
    
        }
    
        [DataContract]
        public class Employee
        {
            [DataMember]
            public string FirstName { get; set; }
            [DataMember]
            public string LastName { get; set; }
        }
    }
    

    然后修改服务定义

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace SilverlightApplication6.Web
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "EmployeeService" in code, svc and config file together.
        public class EmployeeService : IEmployeeService
        {
            public void DoWork()
            {
            }
    
    
            public Employee[] GetEmployees()
            {
                return new Employee[]{
                    new Employee(){FirstName="ares",LastName="chen"}
                };
    
               
            }
        }
    }
    

    【注意】目前我们只是做演示,还没有读取SharePoint

    5. 测试该服务,选中svc文件,然后右键,在浏览器中查看

    image

    如果能看到下面这样的界面,则表示服务是成功的

    image

    然后,我们可以找到一个专门的测试工具,来确认该服务真的是可以运行的。可以在下面找到一个工具

    image

    image

    image

    image

    双击左侧的GetEmployees

    image

    点击”Invoke”按钮

    image

    点击“OK”

    image

    到这里为止,我们就确认了该服务确实是可以正常工作的。

    6. 在Silverlight应用程序中使用该服务

    首先,我们要在Silverlight应用程序中添加服务引用

    image

    image

    点击“OK”之后就可以在程序中生成所谓的客户代理

    image

    那么到底如何使用这个服务呢?

    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;
    
    namespace SilverlightApplication6
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                Loaded += new RoutedEventHandler(MainPage_Loaded);
            }
    
            void MainPage_Loaded(object sender, RoutedEventArgs e)
            {
                localhost.EmployeeServiceClient client = new localhost.EmployeeServiceClient();
                client.GetEmployeesCompleted += new EventHandler<localhost.GetEmployeesCompletedEventArgs>(client_GetEmployeesCompleted);
                client.GetEmployeesAsync();
            }
    
            void client_GetEmployeesCompleted(object sender, localhost.GetEmployeesCompletedEventArgs e)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    Employees.ItemsSource = e.Result;
                });
    
            }
        }
    }
    【注意】我再次强调,在Silverlight中访问外部的数据或者资源,都是异步的模型。WCF这种场景会自动生成一些方法,来做异步调用。
    

    现在可以按下F5键进行调试了,看看会有什么效果?

    image

    好了,现在我们就已经确认了Silverlight程序能够正确调用到WCF的服务。至于下一步,我们就来修改WCF服务中具体的实现,我们让它去访问SharePoint好了。

    【注意】通过这个例子,大家应该对面向服务的开发有更深的印象。面向服务的开发,客户端无需关心到底服务是怎么实现的,数据在什么地方。

    7. 修改服务实现代码

    等等,我们应该用什么方式去访问到SharePoint呢?我们依然可以使用服务器对象模型或者客户端模型。这个例子中我们使用客户端模型,实际上与控制台程序没有什么大的差别

    【注意】关于在控制台程序中访问客户端模型,请参考http://www.cnblogs.com/chenxizhang/archive/2010/04/26/1721653.html

    image

    修改代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    using Microsoft.SharePoint.Client;
    
    namespace SilverlightApplication6.Web
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "EmployeeService" in code, svc and config file together.
        public class EmployeeService : IEmployeeService
        {
            public void DoWork()
            {
            }
    
    
            public Employee[] GetEmployees()
            {
    
                var url = "http://localhost:45223/sites/dev";
    
                using (ClientContext ctx = new ClientContext(url))
                {
                    ctx.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
                    var web = ctx.Web;
                    ctx.Load(web);
                    ctx.Load(web.Lists);
                    ctx.Load(web, w => w.Lists.Where(l => l.Title == "Employees"));
                    ctx.ExecuteQuery();
    
                    List list = web.Lists[0];
                    CamlQuery camlQuery = new CamlQuery();
                    camlQuery.ViewXml = "<View><Query><Where><Lt><FieldRef Name='Age' /><Value Type='Number'>60</Value></Lt></Where></Query><RowLimit>100</RowLimit></View>";
    
                    ListItemCollection collListItem = list.GetItems(camlQuery);
    
                    ctx.Load(collListItem);
                    ctx.ExecuteQuery();
    
                    List<Employee> emps = new List<Employee>();
    
                    foreach (var item in collListItem)
                    {
                        emps.Add(new Employee()
                        {
                            FirstName = item["FirstName"].ToString(),
                            LastName = item["LastName"].ToString()
                        });
                    }
    
                    return emps.ToArray();
                }
    
               
            }
        }
    }
    

    然后,我们再次按下F5键进行调试

    image

    这样,我们就比较好的解决了Silverlight跨站访问的问题。事实上,我认为虽然可以通过在网站中定义所谓的跨站策略来支持Silverlight访问,但并不见得是非常好的做法。我们通过中间服务的方式来做,能更加易于维护和管理。

    有的朋友可能会问啦,我没有看到在Silverlight程序的什么地方指定了服务的地址呀,它是怎么定位服务的呢?

    其实是有一个配置文件

    image

    在编译好的那个 xap包中也是有这个文件的

    image

    也就是说,它其实是读取该配置文件,然后决定要访问哪一个服务的。

    那么,如果希望Silverlight程序能够动态地根据自己所在网站位置,来访问服务。而不是硬编码的方式。则可以尝试修改一句代码

    image

    大家可以思考一下,为什么要这么修改呢?

  • 相关阅读:
    upgrade和update的区别
    批处理文件的几种路径扩展
    CMD does not support UNC paths as current directories.的巧妙解决方案
    让批处理不回显错误信息
    python中那纠结的os.system()与空格处理
    jQuery Mobel 学习相关资料整理(一)
    c#获取某月的第一天和某月的最后一天
    Umbraco网站制作(七) 调用外部用户控件
    Umbraco网站制作(八) 实现伪静态
    Timeout 时间已到。在操作完成之前超时时间已过或服务器未响应。
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1722881.html
Copyright © 2011-2022 走看看