1

さて、ユーザーからのリクエストがあり、イベントレシーバーを使用してそれを実現したいと思います。

基本的に彼女が望んでいるのは、ユーザーがドキュメントをアップロードできるドキュメントライブラリを用意することです。各ドキュメントには、「UserA--Customization.docx」のようなファイル名が付けられます。これで、ユーザーが同じ名前の多くのドキュメントをアップロードできることが想像できるので、ファイルに自動的に番号を付けます。したがって、UserAが最初のドキュメントをアップロードする場合、SharePointは名前の後に番号を追加して、ファイルの名前を「UserA-Customization-1.docx」にし、次に2番目のドキュメントをアップロードして「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; 
}

このコードのどこが間違っているのですか?助けてくれてありがとう!

編集:これは、VisualStudioのコンソールアプリで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:わかりました、このようなものはどうですか?

//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のクエリを本当に理解していません。これを変更して、目的の動作を実現するにはどうすればよいですか?(まったくの初心者の質問である場合は申し訳ありませんが、これまでC#とEventReceiversを扱ったことがありません)
-しばらくBuildArbitraryQueryを見た後、ある程度理解できたと思いますが、基本的には何も変更する必要はありませんか?ファイルの名前と列の名前をパラメーターとして受け取るので、問題ないはずですよね?

また、リスト内のアイテムはClientA Request-3.docxのようなものになるため、ファイル名をBuildArbitraryQueryに送信すると、完全一致ではなく部分一致を見つけることができます。たとえば、BuildArbitraryQueryが受け取るファイル名がClientA Request.docxの場合、そのClientAからの他のすべてのリクエストを見つけることができますか?では、ClientA Request-1.docx、ClientA Request-2.docxはすべて計算に含まれますか?

4

1 に答える 1

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;
   }
于 2012-08-17T16:53:50.380 に答える