Генерация уникальной случайной строки в библиотеке документов SharePoint - PullRequest
0 голосов
/ 10 июля 2009

Я работаю над настройкой библиотеки документов 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);
    }

}

}

Ответы [ 3 ]

1 голос
/ 10 июля 2009

Несколько вещей:

  • Вам не нужно получать ссылку на listItem и использовать listItem.Update (). Достаточно просто установить AfterProperties.

  • Предотвратить многократное срабатывание одного и того же события, заключив код метода ItemAdding в:

this.DisableEventFiring();
try
{
    // ...
}
finally
{
    this.EnableEventFiring();
}
  • Запустите SPDisposeCheck поверх вашего кода. У вас может быть утечка памяти на объекте SPSite с new SPSite().OpenWeb().

  • Прочитайте Временные решения для обработчиков событий ItemAdding / ItemAdded . Мне никогда не приходилось это делать, но использование отображаемого имени вместо внутреннего имени может решить проблему.

  • В случае отчаяния используйте ItemAdded (). Получить полную ссылку на оригинальный элемент и обновить его.

0 голосов
/ 14 июля 2009

Я смог заставить это работать. Вот готовый код:

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 голосов
/ 10 июля 2009

listItem.Update (); Вероятно, генерирует исключение NullReferenceException, вы можете увидеть сообщение об ошибке в журнале SharePoint (или при подключении к w3wp), но ошибки от получателей событий не будут отображаться конечному пользователю. Они просто отменяют событие.

Кроме того, вам не нужно вызывать обновление для элемента списка или в Интернете в ItemAdding. И когда вы создаете SPWeb для текущего веба в приемнике событий, вы можете вместо этого использовать SPItemEventProperties.OpenWeb (). Это спасает вас от вызова «new SPSite ()», который вы фактически забыли использовать в приведенном выше коде. Это может привести к проблемам, если у вас средняя или высокая нагрузка на ваш сайт. SPDisposeCheck - хороший инструмент, который можно использовать для поиска таких проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...