Office2003 SP1正式发布了,你可以在
这里下载到完整的安装文件。InfoPath 2003 SP1也包含在这个升级包里面。
同时,InfoPath 2003 Toolkit for VS.NET也已经提供了正式版本的
下载,但是,但是,偏偏没有中文版本的,而这个Toolkit安装时会检测VS.NET的语言版本,看来我只能再等等了...
TheServerSide.Net上有一篇不错的文章,“10 Ways to Make Your Code More Testable”(10种让你的代码更具可测性的方法),这10种方法中,有几项不但是让代码更具可测性的方法,也是写代码时必需遵循的基本Principla,但也有几项非常有意思的:
只要可行,就让方法返回一个值。这样不但可以让代码更加容易被测试,而且也更加容易让调用者了解它的运行状态。不过作者也说了这个方法并非是“非此即彼”,而是“as much as possible”。
对于牵涉到包含了数据库的操作,这篇文章提出的解决方法就是很常见的Mock Data Access Object,即在测试时使用一个并非真正去读写数据库的假数据存取对象,来模拟真正的DAO的行为。
说到牵涉到数据存取的测试,在单元测试领域这的确是一个容易让人挠头的问题。在这里我郑重推荐MbUnit这个工具,它内置了两种最常见的解决这个问题的方法,使我们的日子更轻松了。
1、RollBackAttribute,这个特性利用COM+的Transaction,将整个测试方法的操作置于一个事务里面,来达到自动回滚的目的。
[Test]
[RollBack]
public void TestMethod()
Roy Osherove有一篇文章比较详细的对这种方法进行了描述。
2、完整恢复数据库,这个方法基于一种很简单的数据恢复方式:在某个地方(通常是测试开始前或结束后),让数据库根据我们提供的Backup文件自动恢复。
[TestFixture]
[SqlRestoreInfo("connectionstring","databasename",@"c:\db.bak")]
public class TestClass
{
[Test]
[RestoreDatabaseFirst]
public void TestMethod()
“SqlRestoreInfo”特性提供了必要的连接字符串、数据库名,和数据库备份文件信息,“RestoreDatabaseFirst”特性指明了在执行测试方法前先用备份文件来恢复数据库。
最后,介绍一个系列文章,Automating Unit Testing With a Base Class Posts,讲解了一个进行“自动化”测试的方法。
一、本书介绍
本书提供了基于Microsoft新一代协作门户平台SharePoint Portal Server 2003的开发各个方面的指导和答疑。主要面向读者为程序员、企业IT Pro人员。开发平台为.NET Framework 1.1。本书示范代码所用语言为C#。预计全书350-400页。
二、章节结构
第一章 SharePoint介绍
这一章介绍了SharePoint的基本概念、功能,它在微软协作平台策略中的地位。并解释了SPS和WSS的区别。
本章还将解释下面的问题:什么是Microsoft SharePoint Portal Server 2003?什么是Windows SharePoint Services,它和SharePoint Portal Server有什么区别?
第二章 SharePoint Portal Server 2003的部署和管理
这一章简明讲解了如何部署和管理SPS2003。
将包括下面的要点:
SharePoint Portal Server 2003的安装需求,以自带MSDE作为数据库的安装过程,以SqlServer2000作为数据库的安装过程。
什么是门户站点?如果创建门户站点?什么是子站点?如何创建子站点?
用SharePoint扩展原有虚拟服务器站点。什么是文档库?如何管理文档库权限?SharePoint用户和AD用户有何关系?
第三章 定制SharePoint站点
这一章讲解了如何利用FrontPage来定制SharePoint站点,修改其页面。介绍了用于在SharePoint的CAML语言。
第四章 WebPart开发
这一章详细讲解了如何开发WebPart,包括了创建、“可视化”创建、页面导入、CAB部署、MSI部署、添加自定义属性、使用资源、可连接WebPart、事件、访问WSS对象模型。并介绍了如何利用Cache、Client Connection、Multi-Interface Connection来提高WebPart的性能和扩展性。本章将对某些示范的WebPart代码进行详细的讲解和描述。
将包括下面的小节:
(1)WebPart的概念
WebPart的工作原理,和ASP.NET中的控件(Web Control)的异同。WebPart在页面上的生存周期和与页面的交互原理。
(2)创建WebPart
用Visual Studio.NET 2003创建WebPart,手工写WebPart配置文件,将WebPart加入到SharePoint站点的信任控件列表中。
在WebPart中加入自定义属性。
以ASP.NET WebControl的挂念来扩展WebPart,包括:嵌入已制作的User Control、事件回发处理等。
(3)创建可互相连接的WebPart
介绍了如何开发可以相互通信和交互的WebPart。
(4)部署WebPart
介绍三种部署方式:手工部署、CAB部署、MSI部署。
(5)源码剖析
详细介绍和讲解了两个示范WebPart的源码:一个支持用户自己指定文档库名称和显示数量的用于显示一个文档库前N个最新文档列表的WebPart,和两个可以互相连接通信的WebPart。
第五章 文档库EventHandler开发
这一章讲述了如何利用SharePoint中的事件处理器来处理站点文档库中的各种事件,并利用这个事件拦截能力来完成某些自定义功能。
(1)EventHandler的启用和设置
如何在SPS中启动EventHandler,如何为文档库配置EventHandler。
(2)EventHandler的原理和编写
EventHandler是如何工作的,如何在VS.NET中开发自己的EventHandler。
(3)源码剖析
将讲解两个实用的EventHandler的源码。第一个是文档库操作记录器,可以在指定的log文件中记录指定文档库所有的文档操作,第二个是文档库容量限制功能,通过EventHandler来实现对每个文档库的占用磁盘容量进行限制。
第六章 WebService与SharePoint
这一章讲述了如何利用SharePoint自带的WebService,以供自定义的客户端程序远程访问SharePoint站点的内容。本章还讲述了如何开发自定义的WebService以满足自定义功能。本章将对创建自定义WebService做详细讲解。
(1)SPS中的WebService
描述了SharePoint是如何处理站点中的WebService的,SharePoint已经内置了哪些WebService。
(2)调用SPS的WebService
如何在远程引用SPS公开的WebService。
(3)自定制WebService
讲述了如何在SharePoint中添加自己定制的WebService。
(4)源码剖析
示范了如何开发一个远程上传文件的WebService,并开发一个WinForms程序引用这个WebService来上传远程计算机中的文件到SharePoint站点中。
第七章 深入SharePoint对象模型
这一章介绍了如何利用SharePoint对象模型来进行程序开发,以最大化的深入和利用SharePoint的功能。本章讲解了几个最常用到的类并示范了其用法。
(1)SharePoint Object Model总概
讲解了SharePoint Object Model能干什么,它在SharePoint中的地位,以及作为程序员如何利用它。
(2)SharePoint Object Model开发
使用SharePoint Object Model来访问SharePoint站点中的内容。讲解了常用的站点、列表、文档库、文件夹、文件对象模型的用法。
(3)源码剖析
示范了如何利用SharePoint Object Model来将一个将指定文件夹中的文件数据读入到一个DataSet中,然后将这个DataSet的数据在一个WinForms程序中的DataGrid控件中显示出来并进行排序、过滤等操作。
第八章 扩展SharePoint的Workflow引擎
这一章主要是剖析作者开发的SharePoint Workflow Engine,讲解了如何利用SharePoint的EventHandler功能来实现一个可扩展的、可自定义XML流程描述文件的工作流引擎,以实现自定义的公文流转、报表审批等功能。
(1)Workflow引擎的使用
从使用者角度讲解了如何使用这个Workflow引擎,如何定制它的流程描述文件,如何应用它进行文档流传工作。
(2)原理剖析
剖析了Workflow引擎实现的原理,讲解了如何自己修改和扩展它。
眼看着7月进入了下旬,可自己的blog上7月份统计仍然停留在2篇,于是开始担心开心一脚把我踢飞...
其实真实情况是这个月手头一直在进行着一个web项目,所以难免会忙碌一点。说来也是奇怪,从我开始做.NET程序员以来,做产品的时间远远多过做项目的时间(大家别羡慕我哈,嘿嘿),不过做项目有时候真的还是可以得到很多做产品没法接触和体会的东西...
1、保持项目源码规模
嗯,打开VS.NET,创建解决方案,创建DAL项目,创建BLL项目,创建Web项目,创建Entities项目...两天后,在被不停的在项目间切换来切换去搞得头晕以后,我意识到一开始我就犯了一个愚蠢的错误。于是,我花费了一点时间,将各个子项目的内容都移动到了一个统一的Web项目的各个子目录下,呼,整个世界清净了。
教训:如果一个项目的规模不是那么大,盲目的一成不变的按照Architecture结构来划分子项目完全是不必要的,甚至有可能增加跟踪代码的成本。VS2005中Web项目新增的Code子目录特性,可以说用意是深得此要领。
2、ORM,意味着开发速度
这个项目我使用了DevExpress的ORM产品:XPO,它是一个可以完全对开发人员屏蔽数据库操作的透明持久层,而并非常见的在Entity与数据库Table之间定义映射关系后自动进行存取数据操作的ORM。这就意味着,在开发过程中,我可以完全不用去管建表、建字段、取数据之类的所有的数据库相关的操作。根据我的估计,它大约节约了我40%的写代码时间。我承认XPO有这样或者那样的缺点,但是,它最重要的优点,提高开发速度,完完全全的吸引了我。
心得:项目不同于产品,在性能可以接受的情况下,有时候开发效率要远远重要过代码效率,所以,大胆选用ORM吧!但是(生活中总是有那么多的但是),如果整个项目组的成员对ORM都不熟悉,而且有可能在一个为期两个月的项目里面要花费半个月来学习ORM的使用,那么,还是别冒这个风险了...
3、文档重要还是可以工作的程序重要?
其实我到现在还是有点糊涂。我们的客户要求我们在前期撰写非常详细(详细到一个Form上有几个文本框几个按钮,按第一个按钮会出现什么...)的软件计划说明书(这个想法好像倒是很合软件工程的思路),但是我的想法是,与其花费那么大的精力写这样的一份报告,不如直接做一个Prototype的东西,不一定要实现所有的东西,但是可以给客户对产品的功能有一个更加直观的了解和印象,然后我们可以就这个Prototype进行MileStone式的开发,一步一步让它接近于最终的成型产品。至于那个详细之极的软件计划书,如果亲爱的客户能够在确认它以后将需求固定下来,我倒也很乐意这样干,但是好像没有谁能担保它的“有效期”,那么它的意义我就很值得怀疑了。
心得:大家对这个有何心得呢?
“无刷新页面”,只是一种不确切的效果描述(其实还有其他各种方法来实现这个效果),更确切的说法是:在页面上用JavaScript调用服务器端的一个方法,然后处理返回的数据。实现它最标准的方法当然是XMLHTTP。但是,程序员都是懒惰的家伙,每个人都希望能有更方便的方法,或者,更佳的包装。比如,Lostinet的Rane就是对XMLHTTP的一个很好的包装。
终于,在ASP.NET 2.0里面,我们可以轻松的来做到这点了。服务器端任何实现了System.Web.UI.ICallbackEventHandler接口的控件,都可以通过RaiseCallbackEvent()方法来处理从页面上的JS脚本传递过来的请求和数据,处理后,再将结果传回给页面。这项能力的底层仍然是XMLHTTP。
下面是一个简单的演示:
在页面上,我们放上两个文本框和一个按钮:
<INPUT id="txtMessage">
<INPUT onclick="callToServer();" type="button" value="Call to Server">
Result : <INPUT id="txtResult" >
当点击按钮的时候,将调用JS脚本方法callToServer(),JS脚本如下:
function callToServer()
{
var param = document.getElementById("txtUsername").value;
var context = "";
<% = ClientScript %> <% = ClientScript %>
}
function handleResultFromServer(result, context)
{
document.getElementById("txtResult").value = result;
}
handleResultFromServer()方法则负责将从服务器传回的数据写到txtResult这个文本框里面。
再看看服务器端的代码:
public partial class Default_aspx : System.Web.UI.ICallbackEventHandler
{
private String ClientScript
{
get
{
return this.GetCallbackEventReference(this, "param", "handleResultFromServer", "context");
}
}
public string RaiseCallbackEvent(string eventArgument)
{
return "客户端在[" + DateTime.Now.ToString() + "]传送来 [" + eventArgument + "].";
}
}
我们让页面直接实现ICallbackEventHandler接口,然后接口定义的RaiseCallbackEvent()方法中将服务器的时间和传来的数据一起返回回去。
ClientScript属性的作用是,它调用了页面的GetCallbackEventReference()方法,获得了让客户端有能力调用服务器端方法的JS脚本,并输出到页面的callToServer()方法中,这样,点击页面按钮时,就开始执行页面上包含了调用服务器方法的的callToServer()方法。
注意GetCallbackEventReference()方法的参数,在参数中,我们定义了客户端的哪个变量包含了要传递给服务器,服务器方法执行后,调用客户端的哪个方法等信息。GetCallbackEventReference()的详细参看请看这里。
最后,我们这个页面的执行效果就是:

很多使用Kaneboy.SPSWorkflow的朋友一直都希望文档能够跨站拷贝,就是说,在一个流程动作里面,文档可以从一个站点拷贝到另一个站点的指定位置。
今天更新了Kaneboy.SPSWorkflow的版本,新增了两个流程动作,跨站拷贝和文件删除(奇怪,删除这么基本的动作为什么以前都没有加上去呢?),附带的doc文档也随之更新了。
可以在SharePoint Workflow Engine项目站点下载。因为这个版本刚刚发布,稳定性没有足够的保证,如果使用中出现问题,请和我联系。