2009-07-10 17 views
0

"品質ドキュメント"と呼ばれる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

+0

ええ、そんなに書かれていたEngilshがあった、ごめんなさい...。 – Colin

+0

P.S. ItemAddingオーバーライド内の "using"ブロック全体を削除することができます。その中のコードブロックで十分です(oWeb.Update()呼び出しを除く)。親SPWebオブジェクトではなく、ここでSPLIstItemを使用しているだけです。 – Colin

答えて

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を呼び出す必要はありません。イベントレシーバで現在のWebのSPWebを作成する場合は、代わりにSPItemEventProperties.OpenWeb()を使用できます。これは、あなたが実際に上記のコードで処理することを忘れている "新しいSPSite()"呼び出しを保存します。これは、あなたのサイトに中程度から高い負荷がかかる場合、問題を引き起こす可能性があります。 SPDisposeCheckは、このような問題を見つけるのに使用できる優れたツールです。

1

いくつかのこと:

  • あなたはlistItemのへの参照を取得し、listItem.Updateを(使用する必要はありません)。 AfterPropertiesを設定するだけで十分です。

  • 防止にごItemAddingメソッドのコードをラップすることにより、複数回発射から同じイベント:あなたのコードの上に

this.DisableEventFiring(); 
try 
{ 
    // ... 
} 
finally 
{ 
    this.EnableEventFiring(); 
} 
  • 実行SPDisposeChecknew SPSite().OpenWeb()でSPSiteオブジェクトのメモリリークが発生している可能性があります。

  • Workarounds for ItemAdding/ItemAdded Event Handlersの読み取りを持っています。私はこれを行う必要はありませんでしたが、内部名の代わりに表示名を使用すると問題が解決する可能性があります。

  • 絶望の場合は、代わりにItemAdded()を使用してください。元のアイテムへの完全な参照を取得し、それを更新してください。

+0

これは両方の回答がlistitem.updateを必要としないように思われるので、SPSiteブロックと共に削除しました。 "IDを持つフィーチャの定義を決定できませんでした" ここで私のItemAddingイベントは次のようになります: public override void ItemAdding(SPItemEventPropertiesプロパティ) { string documentNum = createDocNum(プロパティ); プロパティ.AfterProperties ["Document_x0020_Number"] = documentNum; base.ItemAdding(properties); } – PushCode

+0

FYIログに表示されているメッセージがこの機能のIDを参照していないことを確認しました。 – PushCode

関連する問題