2009-07-10 5 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

이 코드를 depubug하면 어떻게됩니까? 그것이 파문을 일으키는 줄을 아십니까? – Colin

+0

Jeez, 그곳에는 우스꽝스럽게 쓰여진 Engilsh가 있었는데, 미안 .. – Colin

+0

P. 당신은 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의 웹에서 Update를 호출 할 필요가 없습니다. 그리고 이벤트 수신기에서 현재 웹 용 SPWeb을 만들 때 대신 SPItemEventProperties.OpenWeb()을 사용할 수 있습니다. 위의 코드에서 처리하는 것을 잊어 버린 "새로운 SPSite()"호출을 저장합니다. 사이트에 매체 부하가 높으면 문제가 발생할 수 있습니다. SPDisposeCheck은 그러한 문제를 찾는 데 사용할 수있는 좋은 도구입니다.

1

몇 가지 :

  • 당신은되는 listItem에 대한 참조를 얻을 listItem.Update를 사용할 필요가 없습니다(). AfterProperties 만 설정하면 충분합니다.

  • 방지와 ItemAdding 방법 코드를 래핑하여 여러 번 발사에서 같은 이벤트 : 코드를 통해

this.DisableEventFiring(); 
try 
{ 
    // ... 
} 
finally 
{ 
    this.EnableEventFiring(); 
} 
  • 실행 SPDisposeCheck. new SPSite().OpenWeb()으로 SPSite 객체에서 메모리 누수가 발생할 수 있습니다.

  • Workarounds for ItemAdding/ItemAdded Event Handlers의 읽기 되세요. 필자는이 작업을 수행 할 필요가 없지만 내부 이름 대신 표시 이름을 사용하면 문제가 해결 될 수 있습니다.

  • 절망적 인 경우 대신 ItemAdded()를 사용하십시오. 원래 항목에 대한 전체 참조를 가져 와서 업데이트하십시오.

+0

두 답변 모두 listitem.update가 필요하지 않다고 제안하는 것처럼 보이므로 SPSite 블록과 함께 제거했습니다. "ID가있는 지형지 물에 대한 정의를 결정하지 못했습니다." 내 ItemAdding 이벤트는 다음과 같습니다. public override void ItemAdding (SPItemEventProperties 속성) { string documentNum = createDocNum (속성); properties.AfterProperties [ "Document_x0020_Number"] = documentNum; base.ItemAdding (properties); } – PushCode

+0

참고 사항 로그에 표시되는 메시지가이 기능의 ID를 참조하지 않는다는 것을 확인했습니다. – PushCode

관련 문제