设为首页 收藏本站
查看: 1126|回复: 0

[经验分享] MOSS 2010:Visual Studio 2010开发体验(18)——在独立的Silverlight应用程序中通过WCF访问SharePoint数据

[复制链接]

尚未签到

发表于 2015-9-26 05:42:31 | 显示全部楼层 |阅读模式
  上一篇我讲到了如何在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);
  但这样却仍然是无法运行的,请看下面的错误
DSC0000.png
  这是什么错误呢?其实一点都不奇怪,如果你以前做过Silverlight开发,调用过外部网站的Web Service的话。这叫跨站访问控制,默认情况下,Silverlight是不可以访问外部服务的。
  关于这一点,我之前有一个文章专门介绍,请参考http://www.cnblogs.com/chenxizhang/archive/2010/03/12/1683939.html
  
  那好吧,我们该如何解决这个问题呢?其实很简单,我们可以在当前网站中添加一个服务,让这个服务去访问SharePoint,然后Silverlight访问该服务。这不就可以了吗?
  按照这样的思路,这一篇我准备用WCF来实现该服务,并且演示如何在Silverlight中使用它。我们的目的仍然是筛选得到年龄小于60的员工清单。
  
1. 创建一个独立的Silverlight应用程序
DSC0001.png
DSC0002.png
2. 对页面进行一些必要的设计
DSC0003.png
3. 创建WCF服务
  我们暂时离开Silverlight项目,切换到刚才创建项目时一起创建的一个Web项目中
  
  
  
DSC0004.png
  在这个项目中,我们添加一个WCF服务
DSC0005.png
  
DSC0006.png
  【注意】它会增加两个文件,一个是IEmployeeService.cs(如上图所示),一个是EmployeeService.svc(如下图所示)
DSC0007.png
  同时,还会修改web.config文件如下
DSC0008.png
  【注意】这些属于是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://images.cnblogs.com/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文件,然后右键,在浏览器中查看
DSC0009.png
  如果能看到下面这样的界面,则表示服务是成功的
DSC00010.png
  然后,我们可以找到一个专门的测试工具,来确认该服务真的是可以运行的。可以在下面找到一个工具
DSC00011.png
DSC00012.png
DSC00013.png
DSC00014.png
  
  
  
  
  
  
  
  
  双击左侧的GetEmployees
DSC00015.png
  点击”Invoke”按钮
DSC00016.png
  点击“OK”
DSC00017.png
  到这里为止,我们就确认了该服务确实是可以正常工作的。
  

6. 在Silverlight应用程序中使用该服务
  首先,我们要在Silverlight应用程序中添加服务引用
DSC00018.png
DSC00019.png
  点击“OK”之后就可以在程序中生成所谓的客户代理
DSC00020.png
  那么到底如何使用这个服务呢?
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键进行调试了,看看会有什么效果?
DSC00021.png
  好了,现在我们就已经确认了Silverlight程序能够正确调用到WCF的服务。至于下一步,我们就来修改WCF服务中具体的实现,我们让它去访问SharePoint好了。
  【注意】通过这个例子,大家应该对面向服务的开发有更深的印象。面向服务的开发,客户端无需关心到底服务是怎么实现的,数据在什么地方。
  

7. 修改服务实现代码
  等等,我们应该用什么方式去访问到SharePoint呢?我们依然可以使用服务器对象模型或者客户端模型。这个例子中我们使用客户端模型,实际上与控制台程序没有什么大的差别
  【注意】关于在控制台程序中访问客户端模型,请参考http://www.cnblogs.com/chenxizhang/archive/2010/04/26/1721653.html
DSC00022.png
  修改代码如下
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键进行调试
DSC00023.png
  这样,我们就比较好的解决了Silverlight跨站访问的问题。事实上,我认为虽然可以通过在网站中定义所谓的跨站策略来支持Silverlight访问,但并不见得是非常好的做法。我们通过中间服务的方式来做,能更加易于维护和管理。
  
  有的朋友可能会问啦,我没有看到在Silverlight程序的什么地方指定了服务的地址呀,它是怎么定位服务的呢?
  其实是有一个配置文件
DSC00024.png
  在编译好的那个 xap包中也是有这个文件的
DSC00025.png
  也就是说,它其实是读取该配置文件,然后决定要访问哪一个服务的。
  
  那么,如果希望Silverlight程序能够动态地根据自己所在网站位置,来访问服务。而不是硬编码的方式。则可以尝试修改一句代码
DSC00026.png
  大家可以思考一下,为什么要这么修改呢?

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-118816-1-1.html 上篇帖子: sharepoint 2013 userprofile 用户信息 下篇帖子: 继续尝试Teamplate Workflow Web Part for SharePoint Portal Server
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表