2009-07-10 114 views
0

我正在自定義一個名爲「Quality Documents」的SharePoint文檔庫,以便在將新文檔添加到該庫時,生成一個隨機唯一的編號並將其應用於名爲「文件號碼」。我編碼下面的功能,但它不起作用。任何人都可以看到什麼可能是問題?沒有任何反應,沒有錯誤,頁面正常工作,但沒有生成文檔編號。有什麼建議麼?在SharePoint文檔庫中生成唯一的隨機字符串

using System; 
using System.Collections.Generic; 
using System.Text; 
using Microsoft.SharePoint; 
using Microsoft.Office.Server; 
using Microsoft.Office.Server.UserProfiles; 

namespace QualityDocHandler 
{ 
    class DocumentHandler : SPItemEventReceiver 
    { 
    /// <summary> 
    /// Generates a random string with the given length 
    /// </summary> 
    /// <param name="size">Size of the string</param> 
    /// <returns>Random string</returns> 

    private string RandomString(int size) 
    { 
     StringBuilder builder = new StringBuilder(); 
     Random random = new Random(); 
     char ch; 
     for (int i = 0; i < size; i++) 
     { 
      ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))); 
      builder.Append(ch); 
     } 
     return builder.ToString(); 
    } 

    private string createDocNum(SPItemEventProperties properties) 
    { 
     int newRnd = 0; 

     do 
     { 
      // set static department 
      string dept = "QUA"; 

      // set date without separators 
      string dateString = DateTime.Today.ToString("ddMMyyyy"); 

      // get 1st random string 
      string Rand1 = RandomString(4); 

      // get 1st random string 
      string Rand2 = RandomString(4); 

      // creat full document number 
      string docNum = dept + "-" + dateString + "-" + Rand1 + "-" + Rand2; 

      using (SPWeb oWeb = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl)) 
      { 
       SPList oList = oWeb.Lists["Quality Documents"]; 

       //create query 
       SPQuery oQuery = new SPQuery(); 

       //configure the query // 
       oQuery.Query = "<Where><Eq><FieldRef Name='Document_x0020_Number' /><Value Type='Text'>" + docNum + "</Value></Eq></Where>"; 

       //get the collection of items in the list 
       SPListItemCollection oItems = oList.GetItems(oQuery); 

       if (oItems.Count > 0) 
       { 
        newRnd = 0; 
       } 
       else 
       { 
        newRnd = 1; 
       } 
      } 
      return docNum; 
     } 
     while (newRnd < 1); 

    } 

    public override void ItemAdded(SPItemEventProperties properties) 
    { 
     base.ItemAdded(properties); 
    } 

    public override void ItemAdding(SPItemEventProperties properties) 
    { 

     string documentNum = createDocNum(properties); 
     using (SPWeb oWeb = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl)) 
     { 
      SPListItem listItem = properties.ListItem; 
      properties.AfterProperties["Document_x0020_Number"] = documentNum; 
      listItem.Update(); 
      oWeb.Update(); 
     } 
     base.ItemAdding(properties); 

    } 

    public override void ItemUpdated(SPItemEventProperties properties) 
    { 
     base.ItemUpdated(properties); 
    } 

    public override void ItemUpdating(SPItemEventProperties properties) 
    { 
     base.ItemUpdating(properties); 
    } 

} 

}

+0

當你將這段代碼打包時會發生什麼?你知道哪個線斷了嗎? – Colin 2009-07-10 17:27:55

+0

Jeez,那是一些低調的Engilsh在那裏,對不起.. – Colin 2009-07-10 17:29:10

回答

0

我能夠得到這個工作。這裏是完成的代碼:

using System; 
using System.Collections.Generic; 
using System.Text; 
using Microsoft.SharePoint; 
using Microsoft.Office.Server; 
using Microsoft.Office.Server.UserProfiles; 

namespace QualityDocHandler 
{ 
    class DocumentHandler : SPItemEventReceiver 
    { 
     private readonly Random _rng = new Random(); 
     private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     private string RandomString(int size) 
     { 
      char[] buffer = new char[size]; 
      for (int i = 0; i < size; i++) 
      { 
       buffer[i] = _chars[_rng.Next(_chars.Length)]; 
      } 
      return new string(buffer); 
     } 

     private string createDocNum(SPItemEventProperties properties) 
     { 
      int newRnd = 0; 

      do 
      { 
       // set static department 
       string dept = "QUA"; 

       // set date without separators 
       string dateString = DateTime.Today.ToString("ddMMyyyy"); 

       // get 1st random string 
       string Rand1 = RandomString(4); 

       // get 2nd random string 
       string Rand2 = RandomString(4); 

       // creat full document number 
       string docNum = dept + "-" + dateString + "-" + Rand1 + "-" + Rand2; 

       using (SPWeb oWeb = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl)) 
       { 
        SPSiteDataQuery q = new SPSiteDataQuery(); 
        q.Lists = "<Lists BaseType='1'/>"; 
        q.Query = "<Where><Eq><FieldRef Name='Document_x0020_Number' /><Value Type='Text'>" + docNum + "</Value></Eq></Where>"; 
        q.Webs = "<Webs Scope='SiteCollection' />"; 
        q.RowLimit = 1; 

        System.Data.DataTable spSiteDataQueryResults = oWeb.GetSiteData(q); 

        if (spSiteDataQueryResults.Rows.Count > 0) 
        { 
         newRnd = 0; 
        } 
        else 
        { 
         newRnd = 1; 
        } 
       } 

       return docNum; 
      } 
      while (newRnd < 1); 
     } 

     public override void ItemAdded(SPItemEventProperties properties) 
     { 
      this.DisableEventFiring(); 
      properties.ListItem["Document Number"] = properties.AfterProperties["Document Number"]; 
      properties.ListItem.SystemUpdate(); 
      this.EnableEventFiring(); 
     } 

     public override void ItemAdding(SPItemEventProperties properties) 
     { 
      string documentNum = createDocNum(properties); 

      this.DisableEventFiring(); 
      properties.AfterProperties["Document Number"] = documentNum; 
      this.EnableEventFiring(); 
     } 

     public override void ItemUpdated(SPItemEventProperties properties) 
     { 
      base.ItemUpdated(properties); 
     } 

     public override void ItemUpdating(SPItemEventProperties properties) 
     { 
      base.ItemUpdating(properties); 
     } 
    } 
} 
0

listItem.Update();可能會拋出NullReferenceException,您可以在SharePoint日誌中(或通過附加到w3wp)看到錯誤消息,但來自事件接收器的錯誤不會顯示給最終用戶。他們只是取消了這個活動。

另外,您不必在ItemAdding中的列表項或Web上調用Update。並且,當您在事件接收器中爲當前網絡創建SPWeb時,您可以使用SPItemEventProperties.OpenWeb()。它爲您節省了「新的SPSite()」調用,您實際上忘記了在上面的代碼中處理這些調用。這可能會導致問題,如果您的網站上有中等到高負載。 SPDisposeCheck是一個很好的工具,可以用來找到這樣的問題。

1

有幾件事情:

  • 你並不需要去的listItem參考,並使用listItem.Update()。只需設置AfterProperties應該就足夠了。

  • 防止因與包裝你的ItemAdding方法代碼發射多次相同的事件:

this.DisableEventFiring(); 
try 
{ 
    // ... 
} 
finally 
{ 
    this.EnableEventFiring(); 
} 
  • 運行SPDisposeCheck在你的代碼。您可能在SPSite對象上有new SPSite().OpenWeb()內存泄漏。

  • Workarounds for ItemAdding/ItemAdded Event Handlers讀。我從來沒有這樣做過,但使用顯示名稱而不是內部名稱可以解決問題。

  • 在絕望的情況下,使用ItemAdded()代替。獲取對原始項目的完整參考並更新該項目。