我非常疯狂地试图让SharePoint列表事件接收器工作。我已经在VS中创建了一个EventReceiver项目,并且可以调试它,但是,断点不起作用。基本上,很多人都遇到过同样的问题,但他们的解决方案似乎都不起作用。我以前发布过这个,我认为我的事件接收器代码应该可以工作,但我似乎无法在列表中工作。(我的代码粘贴在下面)
基本上,我所需要的只是事件接收器重命名上传的文档。考虑这种情况,如果上传的文档名为Client a document,并且是第一个文档,则该文档应称为Client a Document1。如果上传的下一个文档名为Client A document,则应将其重命名为Client A Document2,依此类推。现在,如果上传了另一个文档,名为Client B document,则该文档应仅为Client B Document1,因为没有其他文档具有相同名称。现在我想我下面的代码实现了这种行为(代码是在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();
以下是您应该做的:
- 重新启动IIS"以卸载正在使用的DLL"
- 将您的DLL及其pdb文件放在适合此DLL的GAC文件夹中
- 打开SharePoint网站,以便启动新的w3wp进程
- 将VS项目附加到w3wp,确保在附加到进程对话框中选择托管代码
- 试着上传一个文件6-你现在应该能够抓住破发点了
您可以制作可以在生成后事件中调用的Shell脚本来自动执行所有这些步骤。
您究竟是如何调试的?您需要附加到适当的w3wp.exe进程并添加一个项,如果断点不起作用,通常是因为最后部署的dll的版本比visual studio中的代码更新(即使是最轻微的更改也可能导致这种差异,如新行等)