0

试图让 SharePoint 列表事件接收器工作时,我几乎快疯了。我在 VS 中创建了一个 EventReceiver 项目并且可以对其进行调试,但是断点不起作用。基本上,很多人都遇到过同样的问题,但他们的解决方案似乎都没有奏效。我之前发布过这个,我认为我的事件接收器代码应该可以工作,但我似乎无法让它在列表本身上工作。(我的代码粘贴在下面)

基本上我所需要的只是让事件接收器重命名上传的文档。考虑这种情况,如果上传的文档称为客户端 A 文档并且是第一个文档,则应将其称为客户端 A 文档 1。如果上传的下一个文档称为客户端 A 文档,则应将其重命名为客户端 A 文档 2,依此类推. 现在,如果上传了另一个名为 Client B Document 的文档,它应该只是 Client B Document 1,因为没有其他同名的文档。现在我认为我下面的代码完成了这种行为(代码是在 Robert Christs 的帮助下编写的!)但我不知道如何测试它。

我是上传文档还是创建新文档?我都试过了,没有任何效果,有人知道如何做到这一点吗?我开始对这个要求失去理智。

public override void ItemAdding(SPItemEventProperties properties)
{
   base.ItemAdding(properties);

   SPListItem item = properties.ListItem;

   if (item == null || item["Name"] == null) //item["Name"] == null)
       return; //or better yet, log 

   string oldFileName = item["Name"].ToString();

   int positionOfPeriod = oldFileName.LastIndexOf(".");
   string tempFileName = oldFileName.Substring(0, positionOfPeriod);

   SPQuery query = BuildArbitraryQuery(properties.List, "Name", tempFileName, true);
   int count = properties.List.GetItems(query).Count;
   String fileName, fileExtension;

   if (positionOfPeriod == -1)
   {
       fileName = oldFileName;
       fileExtension = "";
   }
   else
   {
       fileName = oldFileName.Substring(0, positionOfPeriod);
       fileExtension = oldFileName.Substring(positionOfPeriod);
   }

   string newFileName = fileName + "-xx" + count.ToString() + fileExtension;

   item["Name"] = newFileName;

   Console.WriteLine("New File Name: " + newFileName);

   try
   {
       properties.Web.AllowUnsafeUpdates = true;
       EventFiringEnabled = false;

       item.Update();
   }
   finally
   {
       properties.Web.AllowUnsafeUpdates = false;
       EventFiringEnabled = true;
   }
}
/// <summary> 
/// Builds an arbitrary SPQuery which filters by a single column value. 
/// </summary> 
/// <param name="list">The list you will run the query against.</param> 
/// <param name="columnDisplayName">The Display Name of the column you want to filter.</param> 
/// <param name="value">The value to filter against.</param> 
/// <returns>A new SPQuery object ready to run against the list.</returns> 
public static SPQuery BuildArbitraryQuery(SPList list, string columnDocumentName, string value, bool deepSearch)
{
   if (list == null)
       throw new ArgumentNullException("You cannot pass a null list to Helper.BuildArbitraryQuery.");

   if (!list.Fields.ContainsField(columnDocumentName))
       throw new ArgumentException("The SharePoint List \"" + list.Title + "\" does not contain the Field \"" + columnDocumentName + "\".");

   string internalName = list.Fields[columnDocumentName].InternalName;
   SPQuery query = new SPQuery();
   query.Query = "<Where><Eq><FieldRef Name=\"" + internalName + "\"/><Value Type=\"Text\">" + value + "</Value></Eq></Where>";

   if (deepSearch)
       query.ViewAttributes += "Scope='RecursiveAll'";

   return query;
}

编辑: - - - - - - - - - - - - - - - - - - - - - - - - -- 好的,所以我从相同的项目类型(事件接收器)开始做了一个小测试,并创建了一个非常简单的 ItemAdded 方法来将列表项的名称更改为当前日期。现在这适用于自定义列表,但我似乎无法使用文档库。

所以从这个小测试中我知道我可以使用 F5 将事件接收器注册到自定义列表(沙盒解决方案)并对其进行调试,但是文档库有什么不同呢?我粘贴的代码是否不适合我在文档库上尝试做的事情?

这是我用于小型测试的代码,但它不适用于文档库,即使我为文档库而不是自定义列表创建了新的项目类型(这在 ItemAdded 中)

       SPListItem currentItem = properties.ListItem;
       currentItem["Title"] = DateTime.Now.ToString();
       currentItem.Update();
4

2 回答 2

1

这是你应该做的:

  1. 重新启动 IIS“以卸载 DLL(如果使用)”
  2. 将您的 DLL 及其 pdb 文件放在适合此 DLL 的 GAC 文件夹中
  3. 打开 SharePoint 网站,以便启动新的 w3wp 进程。
  4. 将您的 VS 项目附加到 w3wp 确保您在附加到进程对话框中选择托管代码。
  5. 尝试上传文件 6- 你现在应该可以捕捉断点了。

您可以制作可以在构建后事件中调用的 Shell 脚本来自动执行所有这些步骤。

于 2012-09-07T19:39:38.913 回答
0

你究竟是如何调试的?您需要附加到适当的 w3wp.exe 进程并添加一个项目,如果断点不起作用,通常是因为最后部署的 dll 的版本比您在 Visual Studio 中的代码更新(即使是最轻微的更改也会导致这种差异像新线等)

于 2012-09-07T19:07:49.100 回答