RSS

Monthly Archives: 十一月 2008

Live Services Jumpstart第一天

微软最近正在大力推广live services这一套东西(在TechEd中也占了不小的比例)

这个Jumpstart貌似是一个全球的培训活动,北京这边是2天的课程,包括session和HOL,讲师是总部live services team来的

Part 1. Overview

第一节课比较困,不过基本上都是在show一些demo,概念也不是很多。总的来说,live services的目的就是将用户(Users)、设备(Devices,比如PC、Mac、Mobile、XBox之类的)、应用(Application)整合起来。

用户体验到的是Hotmail、Messenger、Live Mesh这样的应用;开发人员面对的是Live Framework(这个明天讲)。而现在的开发人员还是在做一些底层的比如用户系统、目录、存储管理、通讯管理这样的基础架构,到Live Services中这些都由微软提供了,开发人员可以更加关注业务和用户体验。

目前有一个开源的项目是完全用live services构建的:http://www.adventureworksresorts.com

Part 2. Online Identity(其实就是LiveID)

首先就是一堆概述,比如为什么要用LiveID之类的(号称是全球最大用户数的身份验证提供方,可以安全、稳定的提供用户身份验证服务,且免费;目前有很多应用都是以LiveID作为身份的——当然,基本上都是微软的应用)

当然,这里面提到LiveID的意思是说我们可以在自己的应用中使用LiveID作为身份验证服务,也可以将LiveID和已有的验证服务(比如AD之类的)集成起来。在身份集成的APPZ(Authentication, Policy, Profile, Authorization,又是一个拼写的噱头)中,LiveID负责解决Authentication、Policy和部分Profile的问题。

将LiveID集成进我们自己的应用的另一个好处就是安全,所有的登陆操作都在live.com上完成,用户不再会担心网站会保留我们的live的用户名和密码用来做其他一些事情(似乎有些网站就是要直接输入live的用户名和密码的……),所以他一再强调一定不要在不是live.com的网址上输入live的用户名和密码。

LiveID的集成方式主要有三种:

(1)Web Authentication。这种方式基本上就是在我们的页面中嵌一小段html代码,用于显示登陆(或退出登陆)的按钮(或链接)。这种方式基本上就是和传统的第三方验证提供程序一样的工作原理。需要在live services中注册一个AppId,同时指定这个AppId对应的domain,live在做验证的时候会检查跳转回去的地址,如果不是注册的domain的话,就不允许,以放置信息被窃取。这种方式登陆后会返回一个token,这个token是根据AppId、UserId、时间戳和签名加密成的。在界面上,这种登陆方式是跳转到live.com上进行用户登陆,但是这个登陆页面是允许用户进行部分的修改的(通过一段xml上传到live services中),比如css。这个方式最为简单,只是纯粹的身份验证,我们的应用可以直接使用token解析出来的userId作为用户身份的标志。

(2)Delegate Authentication。这个方式要更复杂一些,可以在网站中获取更多关于用户的信息,比如用户的好友列表(Flickr现在似乎就支持这个功能)、用户的照片库之类的。

(3)Client Authentication。客户端程序的验证,验证的时候直接弹出一个Live的控件输入邮箱和密码(有点像msn的登陆界面),登陆后就拥有了这个live的身份,可以无缝的和微软其他的live应用集成(比如通过接口直接发space的blog之类的)。

然后现在LiveID正在(或者已经?)作为OpenID的一个提供方,凡是可以用OpenID作为身份认证的应用,都可以使用LiveID,这个他做了一个demo,不过没有成功……

Part 3. Communication

这部分主要介绍的是Messenger的lib(javascript的),通过这个lib,可以在我们的页面上嵌入一个小型的messenger。我做的HOL里有一个这个,不过非常简单,只是登陆后显示用户名而已,不过是纯前台的,没有任何后台代码。(当然,登陆也是要先跳转到live.com上)另外,也有服务器端的Messnger控件可以用,使用起来更方便一些,拖上去配置几下就行了。

其余的还有可以在应用中做自己的alert(可以通过msn消息做提醒,不过这个似乎要经过微软验证和授权);还有自己的基于msn的p2p应用,叫做Activity(比如写个小游戏之类的,底层通讯是走msn协议,但是不经过服务器),但是目前不支持2人以上,而且同样要经过微软的检查和授权才可以最终发布。

Part 4. Virtual Earth

这个似乎没啥新鲜的东西了,和google那套差不多。不过接口更开放一些,而且可定制的东西更多(可以自己定义3D模型放在自己的地图上),有一大堆服务器端控件可以用,js的似乎也有(记不太清楚了)。现场做了一些demo,比如嵌入一个地图(居然显示了实时的天气情况,3D的,云层,很酷……);西雅图的建筑基本都3D话了,可以直接在里面walkthrough;在自己的应用中设定起点终点,然后画出行车路线图。

有人问这个和google嵌入应用的区别在哪里,他说主要在于license方面、3D方面等等。

Part 5. Live Search

主要就是一些开发接口,同样需要去注册一个appID,然后就可以通过形如: http://api.search.live.net/xml.aspx?Appid=xxxx&query=xxxx这样的request直接取到搜索结果;当然这是xml形式的结果,还有其他形式的通过不同的页面,比如json.aspx

 

Posted by on 2008 年 11 月 27 日 in 未分类

Leave a comment

Tags:

SDP工作流循环初探(下)

之前我们分析了为什么一个简单且看似合理的SPD工作流循环为什么有可能在执行过程中跳出循环的原因,我们的目的在于让这个工作流变得更加稳定。

当一个工作流无法正常工作的时候,可能就会需要其他工作流的帮助。一个人干不了的活,大家一起干。我们需要有另外一个工作流实例,来对第一个工作流进行“监督和提醒”。另外一个工作流即可以放在同一个列表上(因为它们是不同的模板,可以同时产生两个不同的实例),或者另一个辅助列表上。放在同一个列表上在列表设计上比较简单,但是因为同时有两个不同的工作流实例在运行,分析和工作流设计要格外小心;放在多个列表上的话,每个列表上只运行一个实例,通过一个字段关联起来,逻辑上更容易分析,但一旦涉及到迁移和部署就会非常麻烦(见老赵的这篇文章)。为了做测试,我先把所有工作都堆在一个列表上。

思路是这样的,工作流两个模板分成工人和监工两个角色,工人负责干活(执行具体的操作),监工负责提醒工人。工人执行完操作之后,告诉监工“我干完了!”,然后监工说“哦?那么你可以先休息一下”并且在到点之后提醒工人说“嘿!该干活了!”。实际上,这是两个工作流实例互相触发的过程,并通过一个标志位决定目前是工作者应该执行操作,还是监视者执行操作。当然,为了避免之前所说的“触发在退出之前发生”的情况出现,两边都要有一个确认时间段,等待另外一方结束后自己才开始运行。

这两个工作流的设计如下:

首先是工人:

image

然后是监工:

image

其中的Mark就是标记为,决定哪个工作流应该运行,初始值设置成true。执行过程是这个样子的:一开始两边都触发,但因为Mark为true,所以工人开始,监工退出 –> 工人先休息5分钟(偷懒一下) –> 设置标记,触发监工运行 –> 干活后退出 –> 监工被触发后(以为这个实例的触发是由Mark = false引起的,所以监工必然继续运行)先休息5分钟(等工人把活干完并且工人实例退出) –> 设置标记,触发工人实例 –> 工人被触发(同理,它是被Mark = true引起的,所以必然继续运行) –> 休息5分钟(这5分钟的目的就在这里体现出来了,它是在等待监工实例的退出,否则如果监工因为尚未退出没有被工人的后续操作触发,而且工人自己的实例也出现触发早于退出的情况出现时,那么就没有人提醒工人继续工作了) –> ……于是可怜的工人就在监工的控制之下不断地开始计数了。

我们以工人实例的5分钟休息和监工实例的5分钟休息作为代价,换来了两者互相触发的稳定流程。所以这一方法理论上的计数间隔时间是10分钟,据我测试实际时间平均在15分钟左右。

可以高枕无忧了吧任其运行了吧,还不能!为什么呢?在实际的应用中,除了这两者互相触发之外,还可能由用户去修改这个条目,从而唤醒那个已经停止了的实例。让我们来分析一下可能出现的局面:工人正在睡觉(等待监工退出),此时监工已经做完了本职工作退出 –> 就在工人睁开眼睛,准备提醒监工(设置标志位)之前,某个外来用户做了个更新,当头一棒叫醒了监工(因为工人正在运行,所以没有新的工人实例出现) –> 监工懒洋洋地睁开眼睛,发现现在还不应该工作(标志位尚未被工人更新),于是打算退出 –> 而就在监工从醒来发现没有活干到退出的这一段过程中,工人完成了本职工作(设置标记位、计数) –> 这样一来,由于在工人干活的时候监工还没有退出所以新的监工实例没有出现,如果工人干完活退出前就发生了自我提醒的事情(自我触发发生在退出之前),也不会有新的工人实例出现!于是,两个人因为外来者的干扰同时结束了工作,没有人负责计数了!

好吧……我承认这种情况非常极端,我在测试过程中同时开了个Console每隔1-60秒随机更新一下条目作为外部干扰,在流程跑了一整个晚上之后仍然在正常运行(已经计数了31次),但是从理论上来讲,上面的这种情况是仍有可能出现的(如果实例退出时间 > 工人所有的实际操作时间)。为了避免这种情况的出现,我们需要在两个工作流中再次加入等待流程,等待又用户外部干扰产生的意外唤醒退出后再向下执行。

我没有具体做实验,但是设计了这样一种编排方式:

image

在工人中,将Mark标记设置放在暂停之前,以便提前触发监工;监工等待1天让工人干完事情,然后设置标记触发工人,等待5分钟后再做一个HeartBeat(随便更新一个字段)。监工的5分钟和工人的2小时都是为了避免另一方因为外部操作而被唤醒。我们可以讲用户外部操作这个动作插入上述流程中的每个操作之间,来分析外部操作究竟是否会影响到整个计数流程的进行。因为情况比较多,我就不在这里一一分析了。需要保证的是,监工的第二次暂停必须远小于工人的暂停(因为触发是不规律的,要留一个比较大的浮动范围),同时工人的暂停也要远小于监工的第一次暂停。这个流程理论上的计数间隔是1天零5分钟。

文章在这里得到了一个相当复杂,但几乎cover了所有情况的一个解决方案(我说几乎是以为我在做设计时脑袋都大了,不知道是不是漏过了什么信息)。如果各位看官有更好的解决方案,也欢迎在后面留言。

ps. 这个玩意儿在我这边的实际项目背景是这样的:有一个列表,每个条目都有一个RAG(Red, Amber & Green)状态字段,根据不同情况的不同Date Due,在Date Due内RAG状态为绿色;再过一个月之内,RAG变成黄色;超过一个月后RAG变成红色。可以说这是比较常见的一个应用,但之所以采用SPD工作流的方式进行循环触发的原因,首先是客户不允许编写后台代码(否则timerjob轻松搞定这个需求);其次,SharePoint的计算字段中不能采用Today公式,换句话说SharePoint的计算字段不是在取值时计算,而是在条目更新时计算的(所以就算像某

 

Posted by on 2008 年 11 月 23 日 in 未分类

Leave a comment

Tags:

SPD工作流循环初探(上)

作为SharePoint工作流的一个重要编写工具,SPD(SharePoint Designer)以其良好的界面拖拽方式和较为丰富的逻辑、动作越来越多地被用于实际项目的开发应用中。它比SharePoint内置的若干工作流更为强大,功能更完善;而又比Visual Studio的工作流更为简单,几乎不需要了解什么关于WF的知识和概念。

然而,SPD也有很多不完善的地方(这也是VS工作流的生存空间),例如SPD工作流是一个串行流程,换句话说它是一个顺序工作流,而不是一个状态机工作流(虽然它也可以通过某些方式实现状态机工作流的功能,但这不在本文的讨论范围之内);又比如说它不支持循环,即满足某些条件的时候跳回到之前的步骤重新执行——这正是本文要解决的问题。

其实很多文章都提到了关于SPD工作流循环的问题——当然,那些文章的目的是要避免工作流的循环和死锁。先来看一下为什么工作流会产生循环死锁。例如,我们在SPD工作流中设置了当条目变更时自动启动,然后在流程中修改了当前条目的某个字段——于是,这一修改再次自动触发了这一流程,于是工作流开始循环。这是最为简单的一种循环的触发形式,更多的形式比如一个条目的两个工作流互相触发、多个列表之间的工作流互相触发等等。

在那些文章中也都提到了要如何去避免这一循环,其实很简单,加上一个标记位就可以了,用于标记当前这一条目变更是由工作流本身引起的,还是由用户的操作所引起的。在进入工作流第一步,就要先判断这个标记位,如果当前的变更是由工作流引起的,则直接结束工作流,从而避免循环;否则,进行应有的操作,并且在操作后(或前,没有影响),将标记位设置成工作流变更。当然,这一方法需要在用于操作的时候,讲标记位恢复成“用户操作引起工作流”,以便正常触发SPD中的流程。

于是我们不禁想到,这一循环触发的特性是否能够被我们用来进行循环的设计。答案是肯定的,也有若干文章提到了这一点,具体的方法就是在流程中更改当前条目即可。

接下来,我会用一个自动计数的场景来分析一下SPD工作流究竟应该如何进行循环。自动计数的场景非常简单,就是每隔一段时间将条目的某个字段的值自动增量,这用到了SPD中的一个暂停功能、计算功能以及给字段赋值的功能。

我们先来看一下在那些文章中是如何实现这个循环的,SPD工作流的流程如下(当然不要忘了设置成条目变更时自动触发):

image

先来简单的解释一下这一流程,工作流开始的时候暂停5分钟作为计数的间隔,接下来将计数字段进行增量,存储到工作流变量中,然后讲这个变量重新赋值给计数字段。很简单的一个循环,不过先来分析一下其中的一些细节:

(1)关于暂停时间。我们将暂停时间设置为5分钟,但真的就是5分钟就会触发一次么?经实际测试,触发的时间大约在10-20分钟内不等,即使设置成1分钟,也是这个触发几率。一方面,这是由于工作流的默认timer间隔就是5分钟,并不会那么精准的触发;另一方面,这是由.Net 3.0中工作流的一个bug造成的,微软也给出了补丁(见这里),但实际上这个补丁解决的问题是暂停后不再触发的问题。目前我还没有找到能让实际暂停时间缩短到10分钟之内的方法……

(2)也许我们会有一个疑问:为什么先暂停后计数?这和我们常规的思维有些不同,我们通常会觉得应该先计数后暂停,毕竟计数才是这个工作流应该完成的“本分工作”。这个具体的原因我们先放在一边,先看看这个工作流执行的具体状况。

实际测试中,这样一个5分钟间隔的计数器可能跑了大约1-5次之后就停掉了(工作流完成),我做的另一个20分钟间隔的计数器最多的一个条目在运行了15次后也停掉了,于是我做了一个没有间隔的计数器(去掉暂停的步骤)在运行了76次之后也停了……为什么?这个循环中有问题么?

在这里,必须要先明确一些和SharePoint工作流相关重要概念,即工作流模板、工作流关联和工作流实例。所谓的工作流模板就是我们设置的一套规则,工作流如何如何运行,根据什么条件进行分支,进行什么要的操作;工作流关联指的是工作流模板和具体列表、列表条目的绑定关系,即这个工作流在哪个列表上运行;工作流实例是一个工作流模板在一个列表条目上开始运行后产生的实例(用虽然有些偏差但更容易理解的另一个说法,模板相当于类,而实例相当于对象)。SPD设计的工作流实际上是同时完成了模板和关联的操作,开始运行后产生实例。一个非常关键非常重要的地方在于,一个工作流模板关联在一个列表条目上之后,同一时间内只能有一个实例在运行。当已经有实例正在运行的时候,任何操作都不会触发新的实例。

这就解释了我们为什么要把暂停放到最开始的原因。看吧,如果暂停放在最后会怎样:开始计算、复制–>条目变更 –> 试图触发新的工作流实例 –> 引擎发现当前实例还没结束(因为进入了暂停状态,这个实例在睡觉!)所以这一触发被忽略掉 –> 暂停结束,没发生其他的事情 –> 工作流完成。于是这个计数只是在我们修改的时候增量了一次就结束掉了。

但是这依然不能解释为什么暂停放在最前面也会出现工作流停止,退出循环的问题。据我猜测(没有经过证实,但是和Kaneboy讨论后得出的这个结论)是因为工作流的完成需要一定的时间,换句话说,我们应当在头脑中给每个工作流的最后加上一个“退出”的操作,用来结束掉当前的工作流实例。因此,上面那个计数器在运行时就会变成:暂停(当前实例在睡觉) –> 睡醒了,开始干活 –> 计数,条目变更 –> 慢着!事情就在这里出现变化了。这个时候因为条目有了变化引擎想要触发新的实例,但是旧的实例正在退出,究竟是退出快还是触发快?如果退出发生在触发之前,那么触发的时候因为没有实例在运行,新的实例就会顺利产生,进入下一轮计数;如果触发发生在退出之前,那么触发时仍有实例在活着,引擎拒绝生产出新的实例,等到旧实例退出后,工作流就完成了,计数停止。

看!这个简单的计数器并不一定能如我们想象那样的顺利运行。目前我在一台服务器上运行了一个时间间隔为一天的工作流(实际应用中,我们一般也都是以天为单位来工作的),不知道能跑多少天。

文章写到这里并没有结束,因为我们的目的并不是分析它为什么停止,而是要设计出一个不会停止的循环。(就像你对客户说,我知道这个地方为什么出错了!但客户并不会因此就付给你钱,客户
的目的是要你做出一个不会出错的东西)

 

Posted by on 2008 年 11 月 23 日 in 未分类

Leave a comment

Tags:

VS 2010 for SharePoint

貌似终于要支持webpart可视化开发了,虽然还是通过load userControl的方式,相当于内置了QuickPart。剩下的几个特性都很让人期待。

This week at TechEd EMEA in Barcelona,  Jason Zander, the GM for Visual Studio, announced and demonstrated the Visual Studio 2010 tools for SharePoint.  Here’s a quick summary of what he showed:

  • Server Explorer for SharePoint viewing Lists and other artifacts in SharePoint directly inside of Visual Studio

  • Windows SharePoint Services Project (WSP file) Import to create a new solution

  • Added a new web part project item and showed the Visual web part designer which loads a user control as a web part for SharePoint

  • Showed adding an event receiver for SharePoint and using the wizard to choose the event receiver and to just create a source file with that event receiver.

  • Added an ASPX workflow initiation form to a workflow project and showed how this workflow initiation form has designer capability

  • Showed the packaging explorer and the packaging editor which lets you structure the SharePoint features and WSP file that is created

You can learn more on Channel9 and the Visual Studio 2010 homepage.

原文地址:点我

 

Posted by on 2008 年 11 月 14 日 in 未分类

Leave a comment

Tags:

将SharePoint提升为Web应用开发平台

这次TechEd我和老侯讲的Session,在MVP Community Cabana,和其他几个同等类型的session相比起来听众不多

把大致内容和demo的截图总结一下,算个记录,也给没机会去TechEd的留个东西,另外给我们的一些组件做个广告

言归正传,这个Session的表面上的主要内容是应用WSS构建数据跟踪(Data Tracking)类型的协作应用平台,实际上是通过自定义字段类型来拼装SharePoint应用。首先这个应用平台的两个限定词先解释一下:

1、数据跟踪类型的应用,其实按理说应该是叫数据流类型的。基本上就是以数据流转为主的协作应用,比如场地预订、图书借阅之类的

2、协作型应用,也就是说是由一组人或一些角色来共同完成的应用。比如小组、部门或企业内部的。

微软将应用平台按照类型划分为大概如下几种:Lists(由简单数据表构建的数据存储)、Tracking application(数据跟踪类型)、Mini LOB application(简单的小型业务系统)、LOB(Line of business) application(企业核心业务系统)。按照其应用的数量(横轴)和构建复杂度(纵轴),微软给出了这样一张图:

image

数据列表类型的应用虽然构建简单,但占据了大量的数量(例如联系人、通知、讨论、简单的文档共享灯);企业核心的业务系统虽然构建复杂,但应用的数量相对非常少。

先来看看一个应用的组成部分,以及SharePoint在这些部分中的优缺点:

(1)数据结构定义。SharePoint的列表是一个很好的容器,虽然其存储能力有限,但一般来说足够满足一些日常的应用。而且SharePoint列表也如同数据表一样,内置了多种数据类型,并且包含了一些构建应用基本的“应用字段类型”,例如超链接、选项、查阅项等。

(2)视图。SharePoint内置的列表视图功能比较完善,支持数据列的选择、筛选、排序、最大两级的分组等等。不过SharePoint视图没有权限,难以通过视图控制不同角色的查看。

(3)表单。SharePoint列表创建出来之后,会自动生成3个相应的表单:查看、新建和编辑。但是表单的样式、字段的样式都是固定的,即使通过SPD,能够做出的修改也非常有限,难以适应用户多样的需求。

(4)权限管理。SharePoint在发展到WSSv3之后支持到条目级别的权限。但是不支持字段级别的权限,这对于应用来说比较麻烦,难以控制某些字段哪些人可见、哪些人可以编辑。

(5)业务逻辑。SharePoint列表只是一个容器,应用的逻辑一般都需要开发或配置来完成。好在列表的工具栏、下拉菜单都提供了方便的扩展特性,可以加入一些自定义的操作。事件处理程序、工作流也可以在一定程度上满足对条目在逻辑方便的控制。

WSS作为一个以协作为主要目的平台,经常被用于进行文档管理、知识管理、简单的内容共享的应用(也就是对应Lists类型的应用);而且大多数用户都希望SharePoint能够方便的完成复杂一些的协作型应用(也就是图中第二个层次的应用,也是这次session的主要议题)。然而在使用中,我们会发现SharePoint虽然提供了很多方便的特性,但在某些关键方面难以满足我们的需求,无法通过内置功能的拼装达到我们的目的,需要进行二次开发。而这个session的主要目的,就是通过一些开发好的自定义字段类型组件,来方便、快速地拼装出实际的协同应用平台。

自定义字段类型我就不再过多地介绍了,这是WSSv3新加入的特性,极大地扩展了对列表的开发余地。通过自定义字段类型,可以根本地解决表单多样性的问题、从一定程度上解决字段级权限控制和业务逻辑的辅助。

后面就是通过我们一些已有的自定义字段类型,来完成一些特定的功能,最后给出一个由自定义字段类型拼装完整应用的例子。

先来看几个简单的例子:

1、内容类型图标。内容类型也是WSSv3新加入的一个特性,允许我们在一个列表中放置不同结构、同样目的的内容。一旦在列表中开启了内容类型的控制,就可以创建多种内容类型的条目,但是这些条目在列表视图中很难直观地区分开来(内置的方法只能通过显示“内容类型”这个字段来区分,当然,文档库的文档类型图标是一个例外),于是通过这个自定义字段类型,就可以给不同的内容类型设置不同的图标(在视图和新建菜单中),使得应用看起来更加直观和专业。(目前这个图标还可以控制点击后的行为,比如进入查看页面、编辑页面等)。

image image

2、外部图片。在WSS上做新闻编辑或者图片插入的话非常头疼的就是图片上传和图片插入的分离(如果在MOSS上,还可以用发布功能里的那个插入图片来顶一下)。这个字段就是利用一个高级编辑器(FCKeditor)的二次开发接口,将图片的浏览、上传放到了网站的图片库中(第二张图是在浏览网站的图片库,并且可以将新图片从本地上传到图片库中)。

image image

3、Email地址。这个很简单,就是在单行文本的基础上加了Email格式验证,虽然原理和实现都很简单,不过却很有用。

image

4、设置字段的隐藏和只读。这是一个比较复杂的自定义字段,可以根据条目中某个字段的值、当前用户等内容进行一个复杂的表达式计算,来控制某个字段是否显示,或者是否可编辑。

image

5、密码字段。这个没截图……就是在显示、新建、编辑密码的时候打上马赛克,并且在储存的时候用某个私钥进行加密。新建时候要求输入两次,编辑的时候需要输入原密码以及两次新密码。

之后,通过一个完整的会场预订的应用,展示了如何通过自定义字段类型,来快速地拼装这种协作型的应用:

首先,一个会场预订的功能必然会有一个会场的列表。使用一个自定义列表来创建会场列表,包含了会场的标题、所在区、所在酒店和一些相关信息。

1、在很多地点相关或者类型相关的字段中,我们往往能够希望两个甚至多个下拉列表框能够互动,比如说当选择“北京”后,列出北京的区域;选择天津后,列出天津的区域。这可以通过一个自定义字段类型来完成,相关联的父字段、关联的内容都可以灵活定义:

image image

2、作为相关内容,一个场地肯定会有多条相关内容。这也是在应用构建中非常常见的一种主-子表类型的表关联,通过一个外键进行关联。在SharePoint中,查阅项的作用与此非常类似,可以在子表中设置一个指向主表的查阅项(外键)。然而这种查阅项有时是非常不直观的,只能在子表中看到其条目属于哪个主表,难以看到主表条目中有哪些相关的内容。通过一个“反向查阅项”(或者主-子表字段)类型,就可以实现这一功能。设置可以在主表的编辑页面中,直接新建、修改、删除相关的子表字段:

image

实际上这个相关内容是保存在另一个列表中,有一个指向“场地列表”的查阅项。主表编辑页面中的新建、编辑页面直接使用了子表的新建和编辑页面,只不过做了一些小的修改(在表单打开时自动初始化查阅项指向对应的主表条目)。

3、预订场地通过另外一个列表来实现,可以直接进入这个列表新建列表条目,然而更直接也更友好的方式,就是直接在场地列表中对“心仪”的场地进行预订操作(在列表界面和条目界面都可以进行操作,直接转入场地预订列表的新建页面):

image image

4、场地预订列表中为了标示预订的场地,会设置一个查阅项指向场地列表。但如果出于某种考虑,希望讲场地列表和场地预订列表放在不同的网站上(例如场地列表在资源网站上,由资源管理者统一管理;而场地预订列表在会议网站中),就需要借助另一个自定义字段,跨网站查阅项。这个自定义字段和查阅项的功能基本相同,只是SharePoint内置查阅项只能查阅同一网站中的列表,而这个可以跨网站查阅,并且可以指定一个视图做初次筛选(以免查阅项中出现的内容过多难以选取)。(其实跨网站查阅这一功能在SharePoint查阅项中是提供了的,只不过没有开放到界面上)。它的设置界面:

image

5、所有资源预订类的应用都必然有一个需求,那就是冲突检测。一般的做法是将冲突检测放在事件处理程序中,如果有冲突则抛出异常,不过这不够方便,如果能够在填写场地、时间的时候就能实时地检查是否有冲突,那是最好不过了:

image

这是一个挑战想象力、颠覆传统的自定义字段类型,按照惯常的思维方式,列表的字段一定是作为某一种特定的数据存储之用的;然而,这个“时间冲突检测”的自定义字段类型,不保存任何数据,仅是在新建和编辑页面上出现,提供一个操作。

好了,现在我们可以看到这些场地预订的情况了,日历视图能够让显示更加直观:

image

6、最后,一个预订系统必然要有的一项就是管理员的审批操作。“好,这个地方这段时间就归你了。”/“不行,这个地方要留作它用。”管理员的选择无非就是这两种。当预订较少的时候,管理员可以直接通过SharePoint的审批视图依次查看每个条目进行审批;但一旦条目多起来,偷懒的管理员(懒是世界进步的动力,嗯嗯)希望能够一次性审批多个条目。“要是能像邮箱那样给个多选框,让我选中要批准的,再一点鼠标,就全部搞定该多好。”于是又一个自定义字段登场,它同样只作用于展示层,不保存任何数据:

image

配合这个自定义操作,管理员就可以有更多的时间来……咳咳。

至此,一个完整的会场预订功能就拼装出来了。尽管它有一些简单,但是基本上包含了一个数据流转的协作型应用的所有步骤了。而且在这个应用拼装的过程中,除了最后为真正完成多项审批而编写的10行左右代码,整个过程中几乎没有任何代码操作,完全通过自定义字段类型和其他一些webpart的配置就达到了目的。这极大地方便了管理员的操作,于是IT Pro们就有更多的时间用来聊天灌水了(这不是我,嗯,我不是IT Pro,嘿,说你呢……)。

当然,最后这个应用里有一些小trick,比如如何改变列表条目的下拉菜单、如何改变工具栏菜单。当然,你说可以通过feature来做,但是这个demo中的这些菜单没有一个是通过feature完成的。为什么?因为feature只能挂在某中列表类型或者内容类型上,麻烦……至于是怎么做的,等今后有时间再慢慢介绍。

这些自定义字段类型,我们迟早会发布出来,有些简单的可能就直接free了。请关注公司网站:www.servbus.com,或者直接给我发邮件:

 

Posted by on 2008 年 11 月 11 日 in 未分类

Leave a comment

Tags:

Tech.Ed 2008

总的来说这次缩水比较严重,普通session从2天半减到2天,而且场地也变小了,与会者的伙食变差(讲师的还凑合),会场上提供的水到后来就不够用了(speaker room的也没了)。而且这次OFC课程比较少,SharePoint课程也比较少,没有混到课,于是只好借MVP名义报了一节Community Cabana的Session,地方超小,还没有书包送 >.<   等明后天把这个session的内容整理一下发上来,当然也是sharepoint相关的,和侯总一起讲的。

这次会议的几个着重点在于几个新东西:SQL Server 2008、Hyper-V和虚拟化部署(这个课超多)、Azure Service(所谓的云计算)、VS2010(这个名字的叫法很有意思,一般国内team的speker都念成“二零一零”,今天Colin Yu念成“两千零十”,一看就是平时英文说的比中文多的,哈)、一点点windows 7,还有一些不太新的东西,比如UC。剩下的session大都是在炒冷饭,比如我们的……

因为第一天有session,前面在准备,后面在处理一些公司事务,所以第一天就晃过去了。

今天两节印象比较深刻的session,一个是Hyper-V,一个是Colin Yu的Dublin + .Net Services + SharePoint。

Hyper-V从win server 2008出来后已经挺长时间的了,是微软做虚拟化部署解决方案中的一个重头产品,今天我听的那个session是王……(忘了,英文名是Phoenix)和万网的范总,关于虚拟化部署的最佳实践以及SQL Server 2008在虚拟机上的性能分析。基本结论就是hyper-v很牛,很考验服务器(建议配置都是什么16核、32-64G内存、iSCSI存储、3块以上网卡的服务器……)。从性能上来讲,一个相当于0.8个核的虚拟机cpu(就是一个8核系统跑10个虚拟机)相当于T2300 1.6G的双核CPU的性能;内存相当于DDR2的速度;4块300G做RAID1的硬盘在每个虚拟机中的总体性能相当于SCSI的64%,写速度19MB/s。

微软号称用Hyper-V之后性能比物理机器下降8%。范总他们做了一个SQL Server 2008的测试,各项指标大约在物理机的80-90%左右,也还可以接受。另外SQL Server 2008比2005提升了相当大的性能……

Phoenix说目前微软的msdn、technet和20%的www.microsoft已经是跑在Hyper-V环境中的了,根据测试性能只降低了4%。

下一版的Hyper-V还将支持瞬间的虚拟机在服务器间的迁移、以及在online的情况下更改虚拟机硬件配置。可惜这个玩意儿只有64位版,没法自己试……

 

Colin Yu的课是这次TechEd我听的最后一个Session,印象颇为深刻。前面先讲了一堆故事,吹捧了云计算。然后做了一个Demo:把SharePoint相关的一个文档库通过ISB(internet service bus)push到.net services中,然后建了一个工作流在.net services中,在上传文档后触发.net services中的工作流,并返回到SharePoint网站中的任务列表进行工作流操作;随后,又卸掉了这个workflow,在windows application server(代码名Dublin,可以在IIS中host workflow和communication,下一代的application server,windows 7中提供)挂了另外一个类似的工作流。然后SharePoint端未经过任何配置的修改,就能运行这个新的工作流……很神奇 -.-

下课后和Colin聊了一阵儿,说目前Azure Services中的Microsoft SharePoint Services基本上是把WSS搬到了云中,不过存储和计算还是使用的同一台服务器的资源,然后他们正在重写这套类WSS的内容,使用云端存储(SQL Services)等内容真正的把SharePoint在云中实现。另外他们已经有了把Dublin整合入SharePoint的设计,不过这个还得等下下版的SharePoint……O14肯定是来不及了。O14应该会很大程度上提升列表在性能上的问题。

然后跟Colin和上海team的缪瑾和她的同事(忘了叫啥-.-,也是个mm)聊了若干和SharePoint、workflow相关的内容。他们说现在他们很希望能够得到用户关于SharePoint改进方面的反馈,能够把越来越多的反馈内容提供给微软产品组,这样微软就会更加重视中国市场……

聊的很happy,为了回家陪lp,于是没跟他们一起去吃涮羊肉……

 

中途张弛同学借我的相机跟美女姐姐合影……不过为了估计他的形象还是不把照片贴出来了……

贴张移动话筒状的ocean同学,以及李辉同学:

DSC_1762

DSC_1781

 

Posted by on 2008 年 11 月 08 日 in 未分类

Leave a comment