在已部署的3层LightSwitch 应用程序中诊断问题(艾瑞克·埃尔哈特)

[原文发表地址]Diagnosing Problems in a Deployed 3-Tier LightSwitch Application (Eric Erhardt)

[原文发表时间]2011-9-20 13:00

时常LightSwitch 应用程序在开发人员的机器上运行得很完美,但是当部署到互联网信息服务器(IIS)机器上时,它就不再正常运作了。出现的问题范畴包括从IIS配置不当到数据库连接字符串不正确。或者是某个程序集没有部署在IIS机器上。 谨在这儿分享一些我常用的调试技术来帮助系统管理员诊断部署的应用程序中的问题。关于如何配置网络服务器和部署LightSwitch应用程序,更多详细信息可参考Beth Massi’s deployment guide

在我继续讲述之前,正确树立你的期待值。它不是万能的,不能解决你部署应用程序时遇到的所有问题。但是我可以提供一系列的步骤来诊断我们遇到的最常见的问题。每当有人对我说“我的应用程序出故障了”,我首先想到的事情就是这些步骤。如果这些步骤不能帮助你诊断问题所在,但它们至少提供了一些有用的信息,你可以把它们放到论坛里,在那儿或许有人可以帮到你。

可怕的红色X

在LightSwitch中,可怕的红色X类似于Xbox 360中的死亡之环,所以LightSwitch中出现红色X并没有那么悲惨。你没有必要用一个月的时间来修复。但是它也是你的应用程序中存在问题的一个重大暗示。当程序加载数据失败时,屏幕上将显示一个红色X。工具提示信息会出现“数据加载失败,请检查网络连接之后再重试”。

clip_image002

这些红色X实际上意味着在执行查询时,抛出了异常。

所以你该怎么做呢?

LightSwitch有一个少有人知的秘密,那就是它的服务器有一个与ASP.NET tracing相集成的诊断程序子系统。这个子系可以告诉你在运行查询时,哪个异常被抛出。同时它的功能远远比这更强大。你可以用它来追踪向服务器请求的行为以及服务器对每个行为所作的回应。所以即使所有事情看起来在运作,但你可以知道程序真正在做什么。

当创建一个新的LightSwitch应用程序时,默认情况下诊断是被禁用的。这是为性能和安全因素考虑。性能的原因是不言而喻的,即使是服务器上简单的追踪也会降低处理能力。出于安全因素是因为当诊断被允许时和当你允许远程机器来查看诊断时,任何使用你的应用程序的注册用户都可以获取诊断记录。

有5 个应用程序设置可以控制诊断程序子系统的行为:

Name

Possible values

Description

Microsoft.LightSwitch.Trace.Enabled

true, false

Enables diagnostic tracing on the server.  Default is false.

Microsoft.LightSwitch.Trace.LocalOnly

true, false

When set to false, allows machines other than IIS server to retrieve diagnostic information.  Default is true.

Microsoft.LightSwitch.Trace.Level

None, Error, Warning, Information, Verbose

Defines the level of trace information to be logged.  The values are in increasing order, i.e. Warning writes more log entries than Error.  Default is Information.

Microsoft.LightSwitch.Trace.Sensitive

true, false

Enables “sensitive” information to be written to the diagnostic log.  Sensitive means actual data values, such as addresses, balances, etc.  Default is false.

Microsoft.LightSwitch.Trace.Categories

Microsoft.LightSwitch, unlimited other values

The semi-colon separated list of categories that will be enabled at the specified trace level.  Default is Microsoft.LightSwitch.  Extensions may declare more, or you can declare new ones in your own app.

有两种方式可以使用LightSwitch诊断

在发布应用程序之前,修改web.config中的设置

想要修改web.config文件,将Solution Explorer 视图转换到“File View”

clip_image004

可以看出,在运行中的IIS 网络应用程序账号名下,“Login failed for user”出现了一个异常,这就告诉我——我的应用程序尝试用当前的账号来登录SQL Server数据库,然而,这个账号在我的数据库中没有被设置为用户。当我部署时忘了改变连接字符串。它在我的开发机上运行正常是因为在我的账号下运行。但是一旦我部署了,它就在另一个账号下运行了,而这个账号不具有权限来访问数据库。通过改变连接字符串来使用有效证书可以修复这个问题。

我刚才已经演示了如何诊断一个常见的问题:一旦应用程序被部署到外部,数据库证书就不再正常运行。然而,上述步骤可以诊断绝大多数应用程序中弹出来的红色X问题。你可能不会立刻发现问题,就像上面我所操作一样。但它依然可以详细告诉你问题所在。运用诊断程序子系统是每个LightSwitch开发人员应掌握的技巧。

“GetAuthenticationInfo”查询加载失败,远程服务器返回错误信息:没有找到相关资源

clip_image006

如果说之前所讲的红色X是可怕的,那么“GetAuthenticationInfo”的错误信息可能是可憎的。微软众员工花费了大量的时间正在试图去修复这个错误。可问题是,并不是仅仅一个问题可以导致这个错误。似乎有无穷尽的问题可以引起这个错误。这一原因上面已述。当加载应用程序时,“GetAuthenticationInfo”是LightSwitch发出的第一次服务请求。因此,如果你的IIS机器,网络应用程序,虚拟目录等等出现任何配置问题时,这个错误信息就会显示出来。不幸的是,在这种情况下使用上述诊断程序追踪并不能起到作用。很有可能,这个服务调用甚至没有进入到LightSwitch代码中。如此,诊断程序就无法记录信息,因为它不能到达那么远。

因此在这儿为了诊断问题,我们需要使用另一种工具——Fiddler。Fiddler 是每个网络开发人员与技术管理人员应该拥有,可供他们自由处理的工具。它记录了你的电脑与IIS网络服务器之间的所有网络流量。它可以追踪LightSwitch诊断程序所不能做到的。在客户机上下载Fiddler,启动程序,然后再次加载LightSwitch应用程序,在Fiddler里就可以看到网络请求和回应。

clip_image008

启动Fiddler时,你可以在左边看到请求,想要查看交互信息,点击顶部的“Inspectors”标签,为在顶部的请求和在底部的回应选择监视器。我的第三个请求,即“GetAuthenticationInfo”返回了一个回应——“500 – Internal Server Error”这个文档显示了服务器所做的回应。内容如下:

An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.

To enable the details of this specific error message to be viewable on remote machines, please create a <customErrors> tag within a "web.config" configuration file located in the root directory of the current web application. This <customErrors> tag should then have its "mode" attribute set to "Off".

这个信息显示出现了一个错误,但是服务器并没有显示错误的详细信息。所以我们需要配置服务器来找到错误。要做到这点,需要修改网络配置,按错误信息所述,添加“customErrors”部分,然后重新发布应用程序。或者你也可以在IIS Manager里修改设置。在IIS Manager里,导航到左边的Web Application。在“ASP.NET”标题下,双击“.NET Error Pages”。

clip_image010

在右边“Action”组下面,点击“Edit Feature Settings”

clip_image012

在“Edit Error Pages Settings”下,如果你的客户端是在另一台计算机上,选择“Off” ,或者如果你使用IIS机器作为客户端就选择“Remote Only”。

clip_image014

既然关闭了自定义错误,再次到达应用程序,查看Fiddler追踪情况。你应该会仍然得到“500 – Internal Server Error”错误信息,但是这个回应会提供更多信息告诉你错误所在。下面是我所获得的回应:

clip_image016

如你所看,错误信息为“无法识别的属性‘targetFramework’”。在Bing上快速搜索,错误信息显示,我需要确保服务于我的网站的应用程式集区设置为 4.0 framework。要修复这个错误,在IIS Manager右击“Contoso”网络应用程序,选择“Manage Application”–>“Advanced Settings”。将 Application Pool

从“Classic .NET AppPool”改为正确的“ASP.NET v4.0”。做了这些之后,重新加载应用程序,所有的事情都正常运行了。(说明:当使用LightSwitch配置时,Application Pool可以正确地设置,但是在我的例子中,有人偶然修改掉了。)

结论

就如我所说,这两种诊断技术不能解决部署LightSwitch应用程序后遇到的所有问题,但是它们可以先用来帮你决定发生了什么错误。希望这些信息能帮助你解决问题。转换到Bing搜索这个问题,或者转到LightSwitch论坛,使用这些信息来获取一个更快的解决方案。

解决方案包和SharePoint工具的可延续性

[原文发表地址] Solution Packages and the SharePoint Tools Continuum

[原文发表时间] 2011-10-03 07:00

SharePoint2010开发平台的一大好处就是,它把各个站点都保存为解决方案包。解决方案包扩展名为.wsp,储存在.cab文件中,是一种可部署,可再用包的文件。你可以在浏览器,SharePoint设计器2010和微软Visual Studio 2010中创建方案包。在浏览器和SharePoint设计器2010用户界面中,解决方案包也被称为模板。这项灵活的功能让你能在浏览器和/或SharePoint设计器中创建,设计站点结构,然后将这些自定义内容输入Visual Studio 2010,以供后续开发。

自定义内容完成后,你可以将你的解决方案包部署到SharePoint中,在SharePoint中使用。用浏览器修改完现有站点结构之后,你可以重新再来一遍,保存更新站点为解决方案包。

这个工具的可延续性还能让你使用其他一些工具。比如,你可以在微软Visio 2010中设计工作流进程,然后输入到SharePoint设计器 2010,再到Visual Studio 2010。有关如何做到这一点的说明,参见在Visio中创建,输入和输出SharePoint 工作流

要了解更多关于在SharePoint设计器2010中创建解决方案包的信息,参见将SharePoint站点保存为模板。要了解更多关于Visual Studio 2010方案包的信息,参见创建SharePoint 方案包

clip_image001

用测试控制器、测试代理和创建服务器配置TFS环境(Kirk Evans)

[原文发表地址] Configuring a TFS Environment with Test Controller, Test Agent, and Build Server (Kirk Evans)

[原文发表时间] 2011-08-11 07:53

欢迎阅读SharePoint 2010持续集成系列的第二部分。这篇文章会讨论如何配置你的TFS环境。

这个系列的博文介绍了许多新的技术,教你如何自动生成,部署生成,将测试纳入生成过程的一部分。要建立一个项目,依赖程序集必须在该计算机上。这个条件约束下,使得为SharePoint 2007和SharePoint 2010扩展项目使用同一个生成服务器就变得很困难了。你可以使用集中的Team Foundation Server(TFS)服务器和选用你的项目所需的特定生成服务器来解决这个问题。如果你想在控制环境中测试你的应用程序,TFS会实现让你用自己的测试控制器和测试代理来执行测试。

要展示这些技术,我们会为TFS环境配置一个集中TFS服务器,一个测试控制器和代理,以及Team生成服务器。

实验室环境

我们在做的实验室环境模拟了我们在那些使用TFS的公司里经常可以看到的环境。公司把现有的主导控制器,SQL服务器和SharePoint服务器都安装在不同的机器上(无论是物理机还是虚拟机)。开发在独立的机器上完成,而代码则被部署在SharePoint环境上。

我们常看到,公司提供的是分散的TFS环境。一个集中TFS服务器,支持它的数据库提供应用程序,数据库和报告功能,而独立项目团队提供它们自己的生成和测试服务器。这个配置帮助隔离了一个生成服务器成功地生成源代码所需的依赖性,同时通过将生成过程分散到各个服务器,从而也避免了多并发消耗系统资源。

clip_image001

安装在每个机器上的软件:

Machine

Software Installed

DC.SharePoint.lab

Active Directory

SQL.SharePoint.lab

SQL Server 2008 R2 Standard Edition

SPProd.SharePoint.lab

SharePoint Server 2010 Enterprise Edition

SPDev.SharePoint.lab

SQL Server 2008 R2 Developer Edition

SharePoint Server 2010 Enterprise Edition

Office 2010 Professional Plus

SharePoint Designer 2010

Visual Studio 2010 Ultimate

TFS.SharePoint.lab

SQL Server 2008 R2 Standard Edition

Team Foundation Server 2010

TFSBuild.SharePoint.lab

Visual Studio Build Agent 2010

TFSTest.SharePoint.lab

Visual Studio Test Controller 2010

Visual Studio Test Agent 2010

这篇博文将关注配置开发环境的TFS层,创建一个TFS应用服务器,并分离生成和测试代理。这要从使用单服务器拓扑结构,创建一个TFS服务器开始这方面在这里有记录, “场景:在单服务器上安装TFS”(http://msdn.microsoft.com/en-us/library/dd631899.aspx)。

安装TFS 2010

创建一个新服务器,命名为“TFS”,连入SharePoint.lab域。用于安装的账户必须是本地管理组中的成员。习惯性地,我们使用名为TFSSETUP的账户

为TFS和先决条件创建账户

除了安装账户,你还要为TFS环境配置其他账户。账户在安装文件中有详细信息,“Team Foundation组件安装所需的账户”( http://msdn.microsoft.com/en-us/library/dd578625.aspx)。根据提示操作,创建下列域账户:

Account

Description

SQLSVC

Service account for SQL Server services

WSSSERVICE

Service account for Windows SharePoint Services 3.0

TFSSERVICE

Service account for Team Foundation Server

TFSREPORTS

Report reader account

TFSBUILD

Service account for TFS Build

TFSPROXY

Proxy service for TFS

文档提示你要为账户授予额外的权限。要做这个,你要编辑本地组策略(在Windows开始菜单中,输入“Edit group policy”找到控制面板里的这个程序)。

clip_image002

在组策略编辑器中,导航Local Computer Policy / Computer Configuration / Windows Settings / Security Settings / Local Policies / User Rights Assignment,根据文档中指示的权限进行分配。比如TFSSERVICE,TFSBUILD和TFSPROXY账户的权限是以服务权限登录:

clip_image003

clip_image004

安装IIS7

TFS安装指南里的教程还是很完整的。给你的服务器添加Web服务器(IIS)角色,然后添加ASP.NET,Windows授权以及IIS6 管理兼容服务。

安装SQL服务器2008 R2

在SQL安装对话中,选择“新功能或者为现有安装添加功能”。在SQL运行了规则检查之后,安装支持安装文件。输入产品密匙,接受许可,选择SQL功能安装。你需要安装的功能包括:

· 数据库引擎服务(Database Engine Services)

· 全文本搜索(Full-Text Search)

· 解析服务(Analysis Services)

· 报告服务(Reporting Services)

· 客户端工具连接(Client Tools Connectivity)

· 管理工具—完整版(Management Tools – Complete)

安装窗口如下所示:

clip_image005

注意:你无需安装管理工具,不过安装的话可以帮助问题诊断。另外,你也无需安装客户端工具,不过装上也是有好处的,以防你想配置别名或者网络连接时可用。

安装会根据自己的规则来为不同的选择做检测,然后提示你创建一个默认或者命名的例子。在这个例子中,选择一个默认例子。TFS可以和命名实例一起使用,不过需要手动配置。选择默认例子,TFS安装会为解析服务和报告服务做大部分的配置工作。

安装会检测硬盘空间需求,然后提示你为不同的服务提供登录信息。在这个例子中,我们对所有服务使用同样的账户,并提供一个域账户。

clip_image006

此外,请把SQL服务器代理服务开始类型设置为自动。TFS会使用这项服务来安排像过程解析这类的工作。

然后,安装会要求数据库引擎服务的授权模式,然后以SQLServer管理身份提示。选择Windows授权模式,添加对SQL服务器有管理权限的用户。在这个例子中,我们使用名为TFSSETUP的账户来安装管理TFS。此外,我们的DBA会通过SQLADMIN的账户来管理连接。

clip_image007

下一步就是解析服务的配置了。这里,你会再次收到你要有管理身份的提示,所以你只要提供相同的用户,TFSSETUP和SQLADMIN。

配置完解析服务之后,选择“安装本地模式配置(Install the native mode configuration)”选项,对报告服务进行配置。

clip_image008

最后,选择是否希望把SQL服务器错误报告发送给微软,然后验证配置规则并点击安装。

配置TFS

打开TFS管理操控台。点击应用层节点,点击配置安装功能的链接。选择“标准单服务器”选项,点击“启动向导”。

使用向导的一个好处就是,它会为你配置解析服务和报告服务。为SharePoint产品和SQL报告服务提供一个用户账户。文档建议使用域用户账户WSSSERVICE。

clip_image009

注意:标准配置安装向导会安装配置Windows SharePoint Services 3.0。TFS可以配置把SharePoint 2010作为首选,不过需要额外的手动配置步骤。如果你跟着这篇博文进行配置,请确保TFS服务器是和你SharePoint 2010开发的机器是分开的。

使用配置向导来验证所有的设置,并点击配置。如果你收到SharePoint产品的警告,它是在告诉你它会为IIS中默认的Web页面创建一个新的应用池。由于是全新的安装,所以你可以放心地忽略这个警告。

clip_image010

点击配置之后,向导会在你的机器上配置服务。

只要服务安装配置完成,你就能应用最近的更新了。查看可用的TFS 2010最近更新(http://social.msdn.microsoft.com/Forums/en/tfssetup/thread/79396175-af41-45d0-8e59-569af4bb2696)。在写这篇博文的时候,TFS的最近更新是Service Pack 1。

clip_image011

向导完成后,你会看到所有步骤的总结和配置日志的链接。

clip_image012

配置报告服务

安装完成后,你需要添加TFS服务账户(我们用TFSSERVICE作为账户名称),它将是SQL报告服务中的内容管理角色。以管理者身份打开IE,导航至http://tfs/Reports,进入文件夹设置。

clip_image013

点击文件夹设置,打开然后点击新角色分配,添加TFSSERVICE为内容管理者。

clip_image014

配置解析服务

安装文件也包括这个步骤,不过我们提到是为了更完整。为解析服务配置“在失败时重启”。要实现这个,打开Windows中服务控制面板,右击SQL服务器解析服务,选择属性。在恢复标签上,把每一个失败选项设置为“重启服务(Restart the Service)”。

clip_image015

在TFS生成机器上安装生成服务

在TFS生成机器上,安装TF生成服务。要做这个需要启动TFS安装程序,选择只在机器上安装TF生成服务。

clip_image016

安装完成之后,安装TFSService Pack1。

Service Pack1安装完毕之后,配置生成服务。为TFS服务器添加新的连接。

clip_image017

连接了TFS服务器后,选择项目集合。在这个例子中,我们使用TFS安装创建的默认集合。

clip_image018

下一步,配置生成代理,以便在新生成服务器上运行。

clip_image019

下一步,配置用户账户。默认选项使用NETWORK SERVICE,我们推荐你使用域账户,因为可以更容易的进行错误诊断。将域用户账户命名为TFSBUILD。

clip_image020

验证完设置,点击配置。

clip_image021

为TFS测试机器安装测试控制器和测试代理

在TFS测试机器上,安装TFS测试控制器。安装后,对话会提示你安装测试代理。

clip_image022

安装完测试控制器和测试代理后,打开测试控制器配置工具。我们会在之后的博文中深入介绍这个配置,所以现在,只要接受默认并应用设置就可以了。

clip_image023

配置完测试控制器后,使用配置工具配置测试代理。我们要把测试代理配置为以交互过程(interactive process)运行。

clip_image024

下一步就是用控制器注册测试代理,指定账户运行测试代理。在这个例子中,创建一个用户,测试用户1(TestUser1),来运行测试代理。我们会在之后的文章中告诉你如何用测试代理进行编码UI测试。

测试控制器在之前的部分已经进行了配置。在“TFS测试”机器上运行,默认在6901端口上运行。

clip_image025

设置完测试代理之后,向导会执行配置任务。

clip_image026

向导告诉我们要添加账户至本地管理者组。添加完毕之后,重新启动机器,以使设置生效。

重启后,将TFS服务包1(Service Pack 1)应用到TFS测试机器。

当你用测试用户1账户登录机器时,你会看到测试代理会以交互进程运行。

clip_image027

检查配置

设置完环境了,你还需要检查配置。在TFS生成服务器上,打开TFS管理控制台。在团队项目集合节点上选择组成员来添加用户作为项目集合管理者。在这个例子中,我们添加用户CHRISOBRIEN和KIRKEVANS,作为项目集合的管理者。

clip_image028

我们的开发用户(Kirk Evans和Chris O’Brien)是项目集合管理者。正如MSDN话题“为团队项目集合设置管理者权限”中所说的(http://msdn.microsoft.com/en-us/library/dd547204(VS.100).aspx),这些用户必须添加到页面集合管理者组和报告服务内容管理组。

在TFS服务器上创建的WSS3.0页面上,添加开发用户作为http://tfs/sites/defaultcollection页面的集合管理者。

clip_image029

此外,以内容管理者角色添加用户到报告服务。

clip_image030

注意:你可以使用TFS组成员和域组进行安全控制,不过现在,我们先简单地添加两个用户。

创建一个团队项目

在开发服务器(SPDev)上,连接到TFS服务器,创建一个新的团队项目。

clip_image031

创建项目,接受默认设置。这个会配置进程模板,源代码控制分支位置,和SharePoint WSS3.0团队网站。

创建Visual Studio项目

一旦团队项目创建完成,创建一个新的Visual Studio操控应用方案,并添加到源代码控制,选择团队项目在源代码控制阶级下的位置。

clip_image032

这个再次确认了源代码控制正按期望地运作。我们选择创建控制台应用程序是因为我们要用这个来确认我们的生成服务器运行正常。我们会在之后的文章中详细介绍生成SharePoint项目的其他必要步骤。

检查WSS3.0项目门户

创建完Visual Studio项目后,右击Visual Studio 2010团队资源管理方框中的项目,选择“显示项目门户”以确认TFS SharePoint项目门户(WSS3.0)运行正常。

当你进入项目门户,你会看到提到rs进程中止的错误信息,而不是报告。这是因为仓库还没有建成。除了等待安排工作来建立仓库,你可以手动创建。点击下述服务末端:

http://tfs:8080/tfs/teamfoundation/administration/v3.0/warehousecontrolservice.asmx

· 调用ProcessAnalysisDatabase服务,提供完整的processingType参数。

· 调用ProcessWarehouse服务,不为参数提供值。

这些完成之后,门户显示如下:

clip_image033

我们检查了我们能创建一个新团队项目,在源代码控制中添加了源代码,并检查了团队项目门户起来了,也能运行。最后一步就是通过配置生成检查生成服务器的运行。-

配置生成

尽管最后的检查是配置生成,开发机器是唯一用SharePoint 2010代码的机器。因此,生成服务器不能用来生成SharePoint项目,因为缺少依赖组件。我们会在之后的博文中详讲用SharePoint 2010生成所需的依赖组件来配置生成服务器。现在,我们只要创建一个简单的类库项目来检查一下生成是否按我们所期望的运行。

创建一个名为DROPS的文件夹,赋予TFSBUILDS和TFSSERVICE读取/写入的权限。通常,你会在生成服务器上创建这个共享,不过你也可以在TFS服务器或者其他服务器上轻松地创建。

clip_image034

你还可以将读取的权限授权给用户。比如,你有一个开发团队所属的工作域组,你可以把阅读网络共享的权限分配给这个组。

在开发机器上,右键团队资源管理器中的生成节点选择新建生成定义。当新建生成定义提供路径来放置生成时,键入你的共享名称。现在,对所有其它的生成定义值都使用默认设置。

右键团队资源管理器中的生成定义,选择队列新生成(Queue New Build)。我们的生成服务器是用来生成的。

小贴士:一定要检查一下控制台应用程序和它的的.sln文件被签入进源代码控制里。生成控制器不能生成你的项目除非包含了源代码控制中的源代码。

clip_image035

打开DROPS共享位置,检查操控台应用的EXE和生成日志都在文件夹下。

clip_image036

总结

我们在这篇博文中做了许多配置。我们创建了一个新的TFS服务器,一个独立的生成服务器和独立的测试服务器。我们检查了报告服务功能的正确性,SharePoint门户显示报告数据,我们还检查了生成功能的正确性。在之后的博文中,我们会就这几项内容进行扩展包括:配置生成服务器,使其生成SharePoint 2010项目,自动生成部署以及配置测试作为生成进程的一部分。

了解更多信息

场景:在单服务器上安装TFS

TFS组件安装所需的账户

可用的TFS 2010最近更新

为团队项目集合设置管理者权限

如何用TFS团队生成生成SharePoint项目

使用TF生成生成Visual Studio Sharepoint项目

为SharePoint项目创建首个TFS Build流程(Chris O’Brien)

[原文发表地址] Creating your first TFS Build Process for SharePoint projects (Chris O’Brien)

[原文发表时间] 2011-08-25 07:03

你配置了TFS 2010生成之后,你就可以创建一个生成定义来自动构建你的SharePoint代码库了。MSDN上有详细讲述这个方面的内容(参见Visual Studio应用周期管理中的 定义生成过程这部分),而这篇博文则会对构建SharePoint项目所需的特定要求做些指导,给在这方面刚开始的同行们强调一些关键信息。

以下是我们将在这篇博文中讨论的内容概述:

  • 配置生成服务器来编译SharePoint程序集
  • 配置生成服务器来生成SharePoint方案(WAP)包,不仅仅是程序集
  • 创建首个生成定义——过程概述
  • 编辑生成工作流
  • 处理项目间的依赖关系

配置生成服务器以编译SharePoint程序集

根据默认设置,TFS 2010生成代理无法编译SharePoint代码。这是因为这些项目与SharePoint程序集(比如Microsoft.Sharepoint.dll)相关,而且这些程序集不常存在于生成服务器中,所以编译常常会失败。只有一种例外情况,那就是如果SharePoint 2010也直接安装在生成服务器上——介于性能关系,并不推荐这种布局。

要使编译成功,SharePoint程序集需复制到构建服务器上。这个过程在MSDN上有相关文件,微软也提供PowerShell脚本来“收集”SharePoint服务器中的程序集,然后在构建服务器上正确的文件系统位置“安装”它们。所以第一步就是:

1. 按照如何用TFS团队生成来构建SharePoint项目上的详细步骤

2. 使用在MSDN代码库中发布的SharePointProjectToTfsBuildServer.ps1PowerShell脚本(在上述文章中也有链接)

尽管PowerShell脚本多少简化了整个过程,但要注意除了那些默认收集的程序集之外,可能还会需要其他组件。而且,一些SharePoint程序集只能直接从SharePoint机器的GAC中复制(比如在GAC中导航到GAC_MSIL文件夹)。确切的程序集清单要根据你构建的代码而定。作为指南,我在对项目实行CI时,需要的程序集如下:

  • Microsoft.Office.Server.dll
  • Microsoft.Office.Server.UserProfiles.dll
  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll
  • Microsoft.SharePoint.Client.ServerRuntime.dll
  • Microsoft.SharePoint.Linq.dll
  • Microsoft.SharePoint.Portal.dll
  • Microsoft.SharePoint.Publishing.dll
  • Microsoft.SharePoint.Taxonomy.dll
  • Microsoft.SharePoint.WorkflowActions.dll
  • Microsoft.Web.CommandUI.dll

要添加程序集至PowerShell脚本,将37—41行的分配做如下变更:

Original script

$Script:SharePoint14ReferenceAssemblies = @(
"Microsoft.SharePoint.dll",
"Microsoft.SharePoint.Security.dll",
"Microsoft.SharePoint.WorkflowActions.dll"
)

编辑后

$Script:SharePoint14ReferenceAssemblies = @(
"Microsoft.SharePoint.dll",
"Microsoft.SharePoint.Security.dll",
"Microsoft.SharePoint.WorkflowActions.dll",
"Microsoft.Office.Server.dll",
"Microsoft.Office.Server.UserProfiles.dll",
"Microsoft.SharePoint.Client.dll",
"Microsoft.SharePoint.Client.Runtime.dll",
"Microsoft.SharePoint.Client.ServerRuntime.dll",
"Microsoft.SharePoint.Linq.dll",
"Microsoft.SharePoint.Portal.dll",
"Microsoft.SharePoint.Publishing.dll",
"Microsoft.SharePoint.Taxonomy.dll",
"Microsoft.SharePoint.WorkflowActions.dll",
"Microsoft.Web.CommandUI.dll"
)

注意偶尔你会发现添加新代码就意味着生成过程需要添加之前没有安装的其他的SharePoint程序集。

创建首个生成定义——过程概述

在TFS 2010中创建生成定义其实很简单。在这个部分,我们会涉及整个过程以及主要的配置步骤。我们最终会完成一个自动构建,即从最近签入代码中创建WSP,然后复制到下拉位置。在之后的博文中,我们还会展示如何在每次构建之后把WSP部署到SharePoint服务器上,包括引入程序集版本,自动测试等等。值得注意的是,即使是一个很简单的构建都可以使生成添加值布衣出现人为错误。有关实例之一就是在发布模式中生成程序集而非在调试模式中生成。我们现在来看看创建一个新生成定义的过程。(你可以去MSDN上的定义生成过程查看每个部分的详细介绍)。

1. 确保Visual Studio 2010连接上了TFS,然后在团队资源管理器中选择新构建定义,在构建上下文菜单中。

clip_image001

2. 为生成定义命名,并添加描述。

clip_image002

3. 在触发标签上,定义触发,比如构建在何时执行。触发是很重要的,在定义此项构建的类型时起了至关重要的作用。作为实例,你可以在CI触发上做一个简单的构建,日后再(长期)做些完善。大部分类型在意义上是明确的,不过有些不那么明显。详情参见特定生成触发及原因

clip_image003

4. 工作区标签可以指定生成的工作地点。和开发者很像,构建过程对TFS源代码控制中的文件执行“获取最新”操作,这样就需要工作区的映射,确定文件系统中文件存储的位置。

clip_image004

设置工作区的时候,注意考虑以下几点:

– “获取最新”操作包括特定源代码控制文件夹中所有的文件夹和文件。如果你的构建只包括长列表中的一些Visual Studio项目,那构建就不需要整个源代码树了。指定下属文件夹的路径,只包含需要的项目会很高效,而且减少生成时间。

– $(SourceDir)标记对应构建代理的“工作目录”属性的目录(在TFS管理控制台进行配置)。

– 如果你改变了生成代理文件夹中特定的值,注意尽管浏览器对话框看上去是在本地主机上的,但路径使用的是在构建代理上的。因此,你需要自行输入路径而不是浏览位置。

– 为工作区选用较短路径。这是受Windows路径不能超过260个字符的限制,而且在构建工作目录中过多的字符对常规开发来说没有关系,但是涉及到自动构建工序的话,就会因此限制而失败。当然修改生成代理的工作目录的默认属性也可以起到一样的效果。

5. 默认生成标签上,指定默认生成控制器(如果你有多个的话)和位置(Windows共享的文件夹),构建的结果会复制到这些位置。之后的系列中,我们会看到自动部署WSP文件,这个设置会用来复制包至用于测试的SharePoint环境。注意Windows共享(在下图中名为“BuildDrop”)必须存在,而且TFS构建和TFS服务账户必须有读/写许可。

clip_image005

6. 进程标签中可以完成许多重要的设置。这里,我们指定构建中的方案和项目,及使用的生成工作流(我们之后会进行更改),指定其它输入构建工作流的重要的参数。SharePoint生成的最重要的一个参数就是/p:IsPackaging=true值,它是输入MSBuild Arguments域的参数。这个值会告诉生成进程要实现SharePoint工具生成WSP包,就像Visual Studio 2010那样。如果这个遗漏了,那你的生成输出就会只有程序集了。

clip_image006

说到选择需要生成的Visual Studio项目和方案,你要考虑项目间的依赖,在自动生成中仔细地管理。参见之后的“依赖和引用的注意事项”。要查看进程标签上可用的其它设置,请查看MSDN上的使用默认模板定义生成

7. 保留策略标签是用来指定生成保留的时长的。我们无需在这里改变什么,但是了解一下选项还是很有用的。因为在一段时间里发生很多个构建很常见(比如如果触发是“Continuous Integration”的话每一次签入就会引发一次生成),TFS会自动管理这些,所以它们不会永远累积起来。作为默认设置,最近的10个构建会为输出类型保留。

clip_image007

8. 保存生成定义。

9. 完成了初始生成定义之后,可以通过启动一个手动生成来进行测试。右击团队资源管理器中的生成定义,选择排序新生成

clip_image008

10. 生成现在就会运行并在构建资源管理器窗口中显示(会自动打开)。

clip_image009

11. 生成完成之后,双击列表中的项来显示生成总结。点击导航框中的查看日志链接显示详细的日志,如下图所示。

clip_image010

如果下拉位置的Windows共享配置适合(在第5部中详细介绍过),由构建生成的文件现在就会出现了。假设你将客户端机器连接到这个位置,你可以点击生成报告上的打开下拉文件夹链接来打开Windows资源管理器。注意和生成项目相关的程序集也会在这里显示(查看Jeremy Jameson的文章了解如何解决这个)。在列表中,你还会看到程序集,还有从最近的代码中自动生成的WSP文件。

clip_image011

你现在可以为你的SharePoint项目进行自动生成。

编辑生成工作流的基本介绍

有了自定义生成定义,你就会想在一些点上编辑生成过程工作流。虽然通过编辑构建参数,可以改变生成的许多方面,但更多扩展的自定义内容需要对工作流进行改变——比如配置构建以部署WSP包。

在这部分,我们会介绍一些基本的内容,向你展示如何变更简单的工作流。在之后的文章里,我们会介绍具体的变更,设计程序集版本和WSP包部署。

构建工作流原理

MSDN上的开发自定义生成过程中有详尽综合的自定义构建工作流内容,这个话题也在Visual Studio ALM Ranger团队的构建自定义指南中有出色的解释。不过在这里,我们先来了解一些核心的细节:

  • 在TFS 2010 生成中,生成过程以.NET Framework 4工作流形式施行。要编辑工作流就需要在开发机器上安装.NETFramework 4。
  • 生成工作流储存在TFS源代码控制中。使用的是定义中最近签入的版本。
  • TFS 2010与一些样本生成工作流相连。这些可以使用或者复制,修改来生成自定义过程。这些工作流包括:
    • DefaultTemplate.xaml –对大部分需求来说最好的起始点。
    • LabDefaultTemplate.xaml – 通过微软系统中心虚拟机器管理器来支持管理实验环境(比如虚拟机器,片段)。
    • UpgradeTemplate.xaml – 无需重新建造就能使用现有的TFS 2008构建工序(在MSBuild中写入)。

正如.NET Framework 4中的工作流一样,生成工作流是一系列执行实际工作的工作流内容。TFS 2010联系了许多与构建相关的内容,在自定义工作流时很有用。下表列出了在启动自定义生成时常见的重要内容。

Activity

Purpose

InvokeProcess

Used to call an external process e.g. a PowerShell script or .exe.

WriteBuildMessage/WriteBuildWarning/WriteBuildError

Used to write messages of varying severities to the build log.

ConvertWorkspaceItem

Used to get the file system path from the path in TFS source control, or vice-versa.

还需注意的是一些在System.Workflow.Activities中遗留的.NET Framework4的内容,比如SequenceActivityIfElseActivity,能帮你在工作流中施行一些分支逻辑。

自定义生成工作流

这部分会介绍自定义工作流的过程。我们推荐对相连的工作流做备份,并进行修改,让原始工作流为其它生成和引用工作。Visual Studio中的对话会帮你完成这个过程。

1. 辨识相连的满足你需求的最佳启动工作流点(通常是DefaultTemplate.xaml)。

2. 在生成定义进程标签中,点击新按钮,开始复制现有定义。

clip_image012

3. 在出现的对话框中,确保选择了复制现有XAML文件,并且复制的文件是DefaultTemplate.xaml。给新文件做合适的命名,点击确认

clip_image013

4. 点击确认后,你可以点击 连接至源代码控制资源管理器位置文本下的链接,跳转到那里之后,在开发者机器上执行“获取最新”,转至工作区。

clip_image014

5. 双击XAML文件,在工作流设计器中打开。打开工作流之后,导航至进程序列在代理上运行初始化工作区位置。(如果从未接触过编辑工作流,可以参见在复杂的Windows工作流中导航)。确保在Visual Studio中工具盒窗口可见,从工具盒Team Foundation Build Activities中拖出WriteBuildWarning行为。(注意我们使用的是警告而不是标准消息内容,因为消息的严重性相对较低,默认情况下不会显示在生成报告中。)确保WriteBuildWarning行为是“初始化工作区”序列中的最后一个:

clip_image015

6. 通过指定消息编写构建日志来配置消息信息。在属性窗口中,找到消息属性,点击省略号(…)打开表达编辑窗口。输入字符串信息——在我的例子中,我使用的是“我们可以执行程序集版本。”之后的博文中我们会这么介绍。

clip_image016

7. 点击确定,然后保存工作流,签入

8. 手动触发一个生成来测试工作流(使用“排序一个新生成”,就跟我们之前做的一样。)如果变更很成功,除了编译指定的项目和方案,你可以注意一下下列生成报告中的消息:

clip_image017

现在你已经测试了自定义生成工作流。我们要在这个基础上自动部署WSP到SharePoint服务器,这会在之后的系列博文中进行介绍。

关于依赖和引用的注意事项

许多开发者都很熟悉在引用其他程序集时文件和项目相关的区别。对自动生成来说,用项目引用是最简单的方法。这是因为生成顺序是自动评估的,依赖程序集在需要的时候确保构建。这意味着方案和项目签入TFS,在构建项参数中的选择应该设置为选用项目引用。一个好的方法就是将相关项目组成一组放入方案(在依赖间做项目引用),然后在构建项对话框中选择不同的方案。即使在许多项目引用一个“核心”项目时,相比在自动生成中管理文件引用的复杂性,也可以允许在许多方案中存在核心项目。

总结

在这篇文章中,我们从在TFS生成服务器中构建SharePoint项目开始。然后,我们创建了一个新的生成定义(基于与TFS相连的默认生成工作流),这是执行自动生成的基础。我们进一步创建了自定义生成工作流(从复制相连工作流开始),然后引入了编辑工作流的过程。这是我们之后要做更多的变更的基础,比如部署WSP,执行程序集版本,运行编码UI测试等。下一篇博文中我们会涉及这些。

如何为可编辑OData数据源创建RIA Service包

[原文发表地址] How to Create a RIA Service Wrapper for an Editable OData Source

[原文发表时间] 2011-10-11 10:39

简介

LightSwitch内置支持SQL服务器和SharePoint数据源。要访问其他数据源,你要自行编写WCF RIA DomainService。这篇博文会教你如何通过将访问OData Service的方法封装到DomainService的方式来读写OData数据源。

对于那些能用于RIA Services和LightSwitch的OData Services有一些限制条件。

复杂类型

虽然OData和RIA Services都在实体上支持复杂类型,但是LightSwitch并不支持。如果实体上出现复杂类型属性,LightSwitch将会在导入实体时,忽略那个属性。有一些变通的方法可以用来处理这种情况,我们会在其他博文中详细讲这个问题。

无外键的导航属性

OData Service可以包含与外键无关联的导航属性。这差不多就是多对多关系,不过也可能出现0.1到多或者1到多的关系。比如,Netflix OData Catalog在Title和Genre间包含一个多对多关系。不幸的是,RIA Service的关联是基于外键的。如果一个OData的关联不是基于外键的话,那么通过RIA Service就没有很好的诠释方法了。

如果一个OData Service包含了这类关联,那么在LightSwitch中就会没有现存的方法来表示。不过,你可以在RIA Service上添加带参数的查询,它可以被LightSwitch调用。使用这个功能,查询就能代表这些不被支持的关联能被实现了。对Netflix来说,例如,你可以在RIA Service上定义查询GetGenresByTitle和GetTitlesByGenre,它可以调用特定的OData导航属性。

为LightSwitch创建OData DomainService包的基本步骤如下:

  1. 创建一个类库项目
  2. 添加与OData Service相关的服务
  3. 为项目添加WCF DomainService
  4. 添加一个metadata类为LightSwitch提供关于引用的Service所实现的类的特定信息。
  5. 为你的DomainService添加查询函数,去显示OData Service上的每个实体类
  6. 为你的DomainService添加函数来实现创建,更新,删除每一个实体类

步骤1-5在如何为OData数据源创建RIA Service包博文中都涉及到了。这篇博文会继续详细介绍并更新在那个博文中所创建的DomainService。

允许LightSwitch指定连接信息

第一篇博文假定OData Service的地址在你的DomainService中是硬编码的。我们现在将修改我们的类来实现在LightSwitch中使用RIA Service时可以指定地址。

LightSwitch中的Add Data Source向导会提示开发者在添加DomainService数据源时需要一个连接字符串。这个连接字符串会以DomainService的类名储存于web.config文件中为项目所用。我们将会修改我们的DomainService使它在初始化时从web.config文件中获取连接信息。

首先添加引用到System.Web和System.Configuration。

clip_image001[4]

为DomainService类添加描述属性。这个描述会在Add Data Source向导中显示,当需要用户输入连接字符串时。

<Description("Specify the address to the ProductCatalog Service")> _

    Public Class ProductService

Inherits DomainService

修改初始化函数来检测使用LightSwitch所指定地址。

Public Overrides Sub Initialize(ByVal context As System.ServiceModel.DomainServices.Server.DomainServiceContext)

MyBase.Initialize(context)

‘Get connection information from the web.config

If Web.Configuration.WebConfigurationManager.ConnectionStrings(GetType(ProductService).FullName) Is Nothing OrElse String.IsNullOrWhiteSpace(Web.Configuration.WebConfigurationManager.ConnectionStrings(GetType(ProductService).FullName).ConnectionString) Then

Throw New Exception("The address to RIA Service must be provided when attaching to this data source from LightSwitch.")

Else

Dim url As String = Web.Configuration.WebConfigurationManager.ConnectionStrings(GetType(ProductService).FullName).ConnectionString

_context = New ProductCatalog.ProductCatalogEntities(New Uri(url))

End If

    End Sub

RIA Service提供Submit 函数

DomainService的Submit函数会在LightSwitch每次要保存和修改数据源时被调用。Submit函数需要处理每一个变更的实体,然后把改动保存到OData Service。

在我们的OData Service中,每个Product都有与之相关的Category。要确保Product和Category之间的关系正确,我们的RIA Service需要优先处理Categories。通过按优先级重新排列变更实体集,然后去处理它们就可以实现了。这个重新排序需要基于每个OData Service的结构来自定义。下列类会处理变更集的排序。

Public Class ProductEntitiesComparer

Inherits Comparer(Of Object)

     Public Overrides Function Compare(x As Object, y As Object) As Integer

If TypeOf x Is ProductCatalog.Product AndAlso TypeOf y Is ProductCatalog.Category Then

Return 1

ElseIf TypeOf x Is ProductCatalog.Category AndAlso TypeOf y Is ProductCatalog.Product Then

Return -1

Else

Return 0

End If

End Function

    End Class

一旦变更集被重新排序,我们就要对变更集中的每一条记录进行处理。通过调用Submit的基类,就能实现这点。Submit的基类简单地针对每一个实体类型分别调用Update,Create和Delete函数。我们会在之后提供这些函数。

在每个记录都处理之后,我们需要在OData Service中保存这些更改。介于一个特定保存可以包括多个记录,这些记录都互相联系,因此我们要用批量模式进行保存。

Public Overrides Function Submit(changeSet As ChangeSet) As Boolean

‘Reorder the change set to ensure that categories are processed before products. Products are dependent on categories.

Dim c As New ChangeSet(changeSet.ChangeSetEntries.OrderBy(Function(entry) entry.Entity, New ProductEntitiesComparer()))

Dim baseResult As Boolean = MyBase.Submit(c)

_context.SaveChanges(Services.Client.SaveChangesOptions.Batch)

Return True

End Function

Category提供CreateUpdateDelete函数

对每一个函数,我们首先要把Category添加到DataServiceContext对象上。对Update和Delete函数,我们还要指定附加对象所发生的操作是什么。函数如下所列:

Public Sub CreateCategory(ByVal c As ProductCatalog.Category)

‘Add the new category to the service reference context

_context.AddObject("Categories", c)

End Sub

Public Sub UpdateCategory(ByVal c As ProductCatalog.Category)

‘Attach the object to the context and specify that it has been updated

_context.AttachTo("Categories", c)

_context.UpdateObject(c)

End Sub

Public Sub DeleteCategory(ByVal c As ProductCatalog.Category)

‘Attach the object to the context and specify that it has been deleted

_context.AttachTo("Categories", c)

_context.DeleteObject(c)

End Sub

Product提供CreateUpdateDelete函数

这些函数和为Category而设的函数很相似。不过,对CreateProduct函数来说,我们需要告知DataServiceContext,在Product和Category之间有一定的关系(连接)。这样就能保证新添加的Product可以正确地与Category相关连。在单边关系中,这个步骤是必要的。

Public Sub CreateProduct(ByVal p As ProductCatalog.Product)

‘Add the new product to the service reference context

_context.AddToProducts(p)

‘Need to set link between Product and Category (to ensure that inserts to the database are ordered correctly)

‘For existing categories, get the category first

If p.Category Is Nothing Then

p.Category = _context.Categories.Where(Function(c) c.ID = p.CategoryID).FirstOrDefault()

End If

‘Set the link between the product and category

_context.SetLink(p, "Category", p.Category)

End Sub

Public Sub UpdateProduct(ByVal p As ProductCatalog.Product)

‘Attach the object to the context and specify that it has been updated

_context.AttachTo("Products", p)

_context.UpdateObject(p)

End Sub

Public Sub DeleteProduct(ByVal p As ProductCatalog.Product)

‘Attach the object to the context and specify that it has been deleted

_context.AttachTo("Products", p)

_context.DeleteObject(p)

End Sub

总结

这个函数可以扩展到OData Service中,任意多种实体类型都可以。唯一需要做的修改就是Submit和Create <Entity>函数。在Submit函数中,变更集需要重新排序,来保证父类在子类前被处理。在Create <Entity>函数中,实体类型间的连接需要指定单边,或子边的关系。

希望你们喜欢!