好的,我收到了用户的请求,我想使用事件接收器实现它。
基本上她想要的是拥有一个文档库,用户可以在其中上传文档。每个文档都有一个像“UserA - Customization.docx”这样的文件名。现在您可以想象用户可以上传许多具有相同名称的文档,因此我们要做的就是自动对文件进行编号。因此,如果UserA上传第一个文档,SharePoint将在名称后面添加一个数字,这样文件将被称为“UserA - Customization - 1.docx”,然后他上传第二个文档,它将被称为“UserA - Customization - 2”的.docx”。
但是,现在如果UserB想要上传他的第一个文件,它必须编号为“UserB - Customization - 1.docx”,所以基本上计数器需要重新启动,如果它是一个新的文件,并且如果文件名已经从最高编号继续存在。
所以基本上SharePoint需要检查列表中是否存在当前文档的名称,以及它是否在其旁边添加了一个数字,但该数字必须比最高文档大1,因此它只会增加。
有没有办法做到这一点?有什么想法吗?
这是我到目前为止只是为了简单地更改文件名添加“-xx”到文件名,但这不起作用。
public override void ItemAdded(SPItemEventProperties properties)
{
SPFile spf = properties.ListItem.File;
string url = properties.AfterUrl;
int positionOfSlash = url.LastIndexOf("/");
string pathBeforeFileName = url.Substring(0, positionOfSlash);
string newFileName = createNewFileName(url.Substring(positionOfSlash));
string myNewUrl = pathBeforeFileName + newFileName;
DisableEventFiring();
spf.MoveTo(myNewUrl);
spf.Update();
EnableEventFiring();
}
static string createNewFileName(string oldFileName)
{
int positionOfPeriod = oldFileName.LastIndexOf(".");
string fileName = oldFileName.Substring(0, positionOfPeriod);
string fileExtension = oldFileName.Substring(positionOfPeriod);
string newFileName = fileName + "-xx" + fileExtension;
return newFileName;
}
这个代码我哪里错了?谢谢你的帮助!
编辑:这是我在Visual Studio的控制台应用程序中使用的代码,用于将EventReceiver附加到文档库。
using (SPSite site = new SPSite("http://servername:port/subsite1/subsite2/"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["My Doc Library"];
SPEventReceiverDefinition def = list.EventReceivers.Add();
def.Assembly = "DocumentLibrary_ClassLib, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=611205b34d18f14d";
def.Class = "DocumentLibrary_ClassLib.EventReceiver";
def.Type = SPEventReceiverType.ItemAdded;
def.Update();
}
}
编辑#2:编辑#2:
好的,这样的事情怎么样?
//this will get just the name of the file without the extension and I will send that to the
//query builder which will count how many files there are with that name and return
int positionOfPeriod = oldFileName.LastIndexOf(".");
string tempFileName = oldFileName.Substring(0, positionOfPeriod);
SPQuery query = BuildArbitraryQuery(properties.List, "Name", tempFileName, true);
但是现在我并不真正了解BuildArbitraryQuery中的查询,我该如何更改它以给我所需的行为? (对不起,如果它是一个总的noob问题,但我以前从未处理过C#和EventReceivers)
- 看了BuildArbitraryQuery一段时间后我觉得我对它有所了解,基本上我不需要改变什么?因为它接收文件的名称和列的名称作为参数,它应该是好的吗?
此外,由于列表中的项目将类似于ClientA Request - 3.docx,我将文件名发送到BuildArbitraryQuery将能够找到部分匹配而不是完全匹配。因此,例如,如果BuildArbitraryQuery接收的文件名是ClientA Request.docx,它是否能够找到来自该ClientA的所有其他请求?那么ClientA请求 - 1.docx,ClientA请求 - 2.docx都会包含在计算中吗?
答案 0 :(得分:2)
你去,测试它,它的工作原理。
/// <summary>
/// An item was added.
/// </summary>
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
SPListItem item = properties.ListItem;
if (item["Name"] == null)
return; //or better yet, log
string oldFileName = item["Name"].ToString();
SPQuery query = BuildArbitraryQuery(properties.List, "Created By", properties.UserDisplayName, true);
int count = properties.List.GetItems(query).Count;
int positionOfPeriod = oldFileName.LastIndexOf(".");
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;
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 columnDisplayName, string value, bool deepSearch)
{
if (list == null)
throw new ArgumentNullException("You cannot pass a null list to Helper.BuildArbitraryQuery.");
if (!list.Fields.ContainsField(columnDisplayName))
throw new ArgumentException("The SharePoint List \"" + list.Title + "\" does not contain the Field \"" + columnDisplayName + "\".");
string internalName = list.Fields[columnDisplayName].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;
}