演练:使用 IntelliTrace 调试 SharePoint 应用程序
利用 IntelliTrace,您可以更轻松地调试应用程序,包括那些合并有网页的应用程序(如 SharePoint 解决方案)。 传统的调试器只会为您提供应用程序当前时间的状态的快照。 但是,您可以使用 IntelliTrace 来查看(甚至导航到)应用程序中过去发生的事件以及这些事件发生的上下文。
本演练演示如何使用 IntelliTrace 在 Visual Studio 2010 中调试 SharePoint 项目。 此项目合并了一个功能接收器,当激活功能时,该接收器将向任务列表添加一个任务并向公告列表添加一个公告。 当停用功能时,相应的任务将会标记为已完成,并且会再次向公告列表添加一个公告。 但是,这个过程包含一个逻辑错误,会阻止项目正确运行。 您将利用 IntelliTrace 来查找并更正该错误。
本演练阐释了以下任务:
创建功能和功能事件接收器。
使用代码响应功能事件。
使用代码引用任务和公告列表。
使用代码查找并操作列表元素。
使用 IntelliTrace 查找并更正代码错误。
-
提示
您的计算机上的某些用户界面元素的名称或位置可能会与本主题中的说明不同。 这些元素会因您的设置和 Visual Studio 的版本而异。 有关更多信息,请参见 使用设置。
系统必备
您需要以下组件来完成本演练:
支持的 Windows 和 SharePoint 版本。 有关更多信息,请参见开发 SharePoint 解决方案的要求。
Visual Studio 2010 专业版 SP1、Visual Studio 2010 高级专业版 SP1 或 Visual Studio 2010 旗舰版 SP1。
创建功能接收器
首先,创建一个包含功能接收器的空 SharePoint 项目。
创建功能接收器
使用**“以管理员身份运行”**选项启动 Visual Studio。
在**“文件”菜单上指向“新建”,再单击“项目”**。
此时将出现**“新建项目”**对话框。
在对话框顶部,单击列表中的**“.NET Framework 3.5”**(如果尚未选中它)。
在要使用的语言下,展开**“SharePoint”节点,然后单击“2010”**节点。
在**“模板”窗格中,单击“空 SharePoint 项目”,将项目名称更改为“IntelliTraceTest”,然后单击“确定”**。
将显示**“SharePoint 自定义向导”**,您可以在其中指定项目的 SharePoint 站点和解决方案的信任级别。
单击**“部署为场解决方案”,然后单击“完成”**。
IntelliTrace 只可用于场解决方案。
在**“解决方案资源管理器”中,右击“功能”节点,然后单击“添加功能”**。
将显示 Feature1.feature。
右击 Feature1.feature,然后单击**“添加事件接收器”**以将代码模块添加到该功能中。
向功能接收器中添加代码
接下来,向功能接收器中的以下两个方法添加代码:FeatureActivated 和 FeatureDeactivating。 只要在 SharePoint 中激活或停用该功能,这两个方法就会分别触发。
向功能接收器中添加代码
在 Feature1.EventReceiver 类的顶部,添加以下代码以声明用于指定 SharePoint 站点和子站点的变量:
' SharePoint site/subsite. Private siteUrl As String = "https://localhost" Private webUrl As String = "/"
// SharePoint site/subsite. private string siteUrl = "https://localhost"; private string webUrl = "/";
用下面的代码替换 FeatureActivated 方法:
Public Overrides Sub FeatureActivated(ByVal properties As SPFeatureReceiverProperties) Try Using site As New SPSite(siteUrl) Using web As SPWeb = site.OpenWeb(webUrl) ' Reference the lists. Dim announcementsList As SPList = web.Lists("Announcements") Dim taskList As SPList = web.Lists("Tasks") ' Add a new announcement to the Announcements list. Dim listItem As SPListItem = announcementsList.Items.Add() listItem("Title") = "Activated Feature: " & Convert.ToString(properties.Definition.DisplayName) listItem("Body") = Convert.ToString(properties.Definition.DisplayName) & " was activated on: " & DateTime.Now.ToString() listItem.Update() ' Add a to-do task to the Task list. Dim newTask As SPListItem = taskList.Items.Add() newTask("Title") = "Deactivate feature: " & Convert.ToString(properties.Definition.DisplayName) newTask.Update() End Using End Using Catch e As Exception Console.WriteLine("Error: " & e.ToString()) End Try End Sub
public override void FeatureActivated(SPFeatureReceiverProperties properties) { try { using (SPSite site = new SPSite(siteUrl)) { using (SPWeb web = site.OpenWeb(webUrl)) { // Reference the lists. SPList announcementsList = web.Lists["Announcements"]; SPList taskList = web.Lists["Tasks"]; // Add a new announcement to the Announcements list. SPListItem listItem = announcementsList.Items.Add(); listItem["Title"] = "Activated Feature: " + properties.Definition.DisplayName; listItem["Body"] = properties.Definition.DisplayName + " was activated on: " + DateTime.Now.ToString(); listItem.Update(); // Add a to-do task to the Task list. SPListItem newTask = taskList.Items.Add(); newTask["Title"] = "Deactivate feature: " + properties.Definition.DisplayName; newTask.Update(); } } } catch (Exception e) { Console.WriteLine("Error: " + e.ToString()); } }
用下面的代码替换 FeatureDeactivating 方法:
Public Overrides Sub FeatureDeactivating(ByVal properties As SPFeatureReceiverProperties) Try Using site As New SPSite(siteUrl) Using web As SPWeb = site.OpenWeb(webUrl) ' Reference the lists Dim taskList As SPList = web.Lists("Tasks") Dim announcementsList As SPList = web.Lists("Announcements") ' Add an announcement that the feature was deactivated. Dim listItem As SPListItem = announcementsList.Items.Add() listItem("Title") = "Deactivated Feature: " & Convert.ToString(properties.Definition.DisplayName) listItem("Body") = Convert.ToString(properties.Definition.DisplayName) & " was deactivated on: " & DateTime.Now.ToString() listItem.Update() ' Find the task the feature receiver added to the Task list when the ' feature was activated. Dim qry As New SPQuery() qry.Query = "<Where><Contains><FieldRef Name='Title' /><Value Type='Text'>Deactive</Value></Contains></Where>" Dim taskItems As SPListItemCollection = taskList.GetItems(qry) For Each taskItem As SPListItem In taskItems ' Mark the task as complete. taskItem("PercentComplete") = 1 taskItem("Status") = "Completed" taskItem.Update() Next End Using End Using Catch e As Exception Console.WriteLine("Error: " & e.ToString()) End Try End Sub
public override void FeatureDeactivating(SPFeatureReceiverProperties properties) { try { using (SPSite site = new SPSite(siteUrl)) { using (SPWeb web = site.OpenWeb(webUrl)) { // Reference the lists SPList taskList = web.Lists["Tasks"]; SPList announcementsList = web.Lists["Announcements"]; // Add an announcement that the feature was deactivated. SPListItem listItem = announcementsList.Items.Add(); listItem["Title"] = "Deactivated Feature: " + properties.Definition.DisplayName; listItem["Body"] = properties.Definition.DisplayName + " was deactivated on: " + DateTime.Now.ToString(); listItem.Update(); // Find the task the feature receiver added to the Task list when the // feature was activated. SPQuery qry = new SPQuery(); qry.Query = "<Where><Contains><FieldRef Name='Title' /><Value Type='Text'>Deactive</Value></Contains></Where>"; SPListItemCollection taskItems = taskList.GetItems(qry); foreach (SPListItem taskItem in taskItems) { // Mark the task as complete. taskItem["PercentComplete"] = 1; taskItem["Status"] = "Completed"; taskItem.Update(); } } } } catch (Exception e) { Console.WriteLine("Error: " + e.ToString()); } }
测试项目
现在已向功能接收器添加代码,请运行 SharePoint 应用程序以测试该代码是否可以正常工作。 在本示例中,代码中包含一个小错误。 发生该错误后,您将使用 IntelliTrace 跟踪问题。
测试项目
按 F5 运行项目。
在部署之后,该功能会自动激活,从而导致其功能接收器添加公告和任务。
在 SharePoint 启动后,单击导航窗格中的**“列表”**,然后单击“公告”列表和“任务”列表以查看它们的内容。
在“公告”列表中,添加了名为**“Activated feature: IntelliTraceTest_Feature1”的新公告,并向“任务”列表中添加了名为“Deactivate feature: IntelliTraceTest_Feature1”**的新任务。 该任务的状态为“未启动”。
通过依次单击**“网站操作”下的“管理网站功能”、“IntelliTraceTest Feature1”旁边的“停用”以及警告页面中的“停用此功能”**链接,停用该功能。
任务的**“状态”值现在应为“完成”,其“完成百分比”**值应为“100%”。而这些值仍然保持为其默认值。 代码中的错误阻止任务更新。
调试项目
使用 IntelliTrace 查找并修复代码中的问题。
调试项目
在 FeatureDeactivating 方法中,找到 SPQuery qry = new SPQuery(); 行,然后按**“F9”**在该行中插入断点。
因为问题是在停用功能时发生的,所以此行是开始调试的逻辑位置。
按**“F5”**再次运行该程序,重复本主题前面的“测试项目”中的步骤来激活然后再停用该功能。
当在 FeatureActivated 中命中断点时,将显示 IntelliTrace 窗口并列出应用程序到目前为止已执行的所有步骤。
按**“F11”**逐句通过每行代码,直到程序完成。
每次按**“F11”**时,都会向应用程序的 IntelliTrace 调试历史记录中添加一个“Debugger:”行。
程序完成后,单击 IntelliTrace 窗口中的**“全部中断”**链接。
您必须执行此步骤以保存 IntelliTrace 数据。
或者,若要查看应用程序的调用信息,请单击 IntelliTrace 工具栏上的**“打开 IntelliTrace 设置”,然后单击“IntelliTrace 事件和调用信息”**。
通过单击 IntelliTrace 工具栏上的**“保存当前 IntelliTrace 会话”**保存调试数据。
该文件将具有扩展名 .iTrace。
在 Visual Studio 中,单击**“停止调试”**。
打开 .iTrace 文件。
此步骤将打开另一个用于显示 IntelliTrace 摘要页的 Visual Studio 实例,该摘要页提供了异常数据等调试信息以及程序中使用的线程的列表。
展开**“线程列表”,单击“主线程”,然后单击“开始调试”**。
此步骤将使用 .iTrace 数据在 Visual Studio 中启动调试会话。 若要查看 IntelliTrace 窗口中某个事件的其他详细信息,请单击该事件。
因为我们怀疑 FeatureDeactivating 方法中发生了错误,所以单击**“Debugger:”步骤中的“局部变量”**链接以获取 SPListItemCollection taskItems = taskList.GetItems(qry);。
将出现“局部变量”窗口。
在“局部变量”窗口中,展开变量列表,找到 qry.Query,然后验证用于查找任务的查询是否在错误地搜索“Deactive”而不是“Deactivate”。
此错误意味着,在“任务”列表的查询中永远找不到该任务。
重新测试项目
现在已使用 IntelliTrace 确定了问题,请更改错误,然后重新测试项目。
重新测试项目
关闭 Visual Studio 的调试会话,然后重新打开 IntelliTraceTest 项目(如果尚未打开它)。
在代码的查询字符串 (qry.Query = "<Where><Contains><FieldRef Name='Title' /><Value Type='Text'>Deactive</Value></Contains></Where>") 中,将值从 Deactive 更改为 Deactivate。
按**“F5”**再次运行项目。
打开任务列表,然后验证 Deactivate 任务的**“状态”值现在是否已正确设置为“完成”,并验证其“完成百分比”**的值是否设置为 100%。