Пример надстройки SharePoint для автоматической расстановки тегов
В примере ECM.AutoTagging показано, как использовать эту надстройку с размещением у поставщика для автоматической расстановки тегов в содержимом, добавленном в библиотеку SharePoint с помощью данных из настраиваемого свойства профиля пользователя.
Эта надстройка использует удаленные приемники событий, размещенные на веб-сайте Azure, для:
- создания полей, типов содержимого и библиотек документов;
- получения значения настраиваемого свойства профиля пользователя;
- настройки полей таксономии.
Используйте это решение, если вы хотите:
- реализовать удаленные приемники событий в SharePoint Online;
- улучшить результаты поиска, вкладывая дополнительные метаданные в содержимое при его создании;
- классифицировать содержимое;
- модернизировать код до перехода на новую версию SharePoint, если вы прежде использовали приемники событий.
Подготовка к работе
Чтобы приступить к работе, скачайте пример надстройки ECM.AutoTagging из проекта Office 365 Developer Patterns and Practices (Шаблоны и методики разработки для Office 365) на портале GitHub.
Примечание.
Код, приведенный в этой статье, предоставляется "как есть" без какой-либо явной или подразумеваемой гарантии, включая подразумеваемые гарантии пригодности для какой-либо цели, для продажи или гарантии отсутствия нарушения прав иных правообладателей.
Прежде чем запустить эту надстройку, выполните действия ниже.
Создайте веб-сайт Azure и разверните на нем проект ECM.AutoTaggingWeb.
Зарегистрируйте надстройку с помощью страницы Appregnew.aspx в Office 365.
Эта надстройка использует разрешения только для приложений. Необходимо назначить разрешения только для приложений с помощью страницы AppInv.aspx в Office 365. Скопируйте XML-файл из файла AppManifest.xml в диалоговое окно XML-запрос разрешения на странице AppInv.aspx, как показано на приведенном ниже рисунке.
<AppPermissionRequests AllowAppOnlyPolicy="true"> <AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="FullControl" /> <AppPermissionRequest Scope="http://sharepoint/taxonomy" Right="Read" /> <AppPermissionRequest Scope="http://sharepoint/social/tenant" Right="Read" /> </AppPermissionRequests>
В проекте ECM.AutoTaggingWeb в файле ReceiverHelper.cs в методе CreateEventReciever обновите свойство ReceiverUrl, указав URL-адрес своего веб-сайта Azure.
public static EventReceiverDefinitionCreationInformation CreateEventReciever(string receiverName, EventReceiverType type) { EventReceiverDefinitionCreationInformation _rer = new EventReceiverDefinitionCreationInformation(); _rer.EventType = type; _rer.ReceiverName = receiverName; _rer.ReceiverClass = "ECM.AutoTaggingWeb.Services.AutoTaggingService"; _rer.ReceiverUrl = "https://<Your domain>.azurewebsites.net/Services/AutoTaggingService.svc"; _rer.Synchronization = EventReceiverSynchronization.Synchronous; return _rer; }
Создайте пакет и разверните надстройку.
При запуске надстройки с размещением у поставщика для автоматической расстановки тегов в документе начальная страница отображается, как показано на приведенном ниже рисунке. На начальной странице описаны некоторые дополнительные этапы настройки, которые необходимо выполнить, прежде чем назначать или удалять приемники событий.
Использование примера надстройки ECM.AutoTagging
В этом примере используется удаленный приемник событий для автоматической расстановки тегов (добавления метаданных) в документы, которые были добавлены в библиотеку документов с актуальными данными из настраиваемого свойства профиля пользователя.
На приведенном ниже рисунке показан поток процесса автоматической расстановки тегов в документах с помощью удаленного приемника событий.
Чтобы назначить метаданные в только что созданный документ в библиотеке документов с помощью удаленного приемника событий:
Пользователь создает или отправляет новое содержимое в библиотеку документов. В этой библиотеке документов назначается удаленный приемник событий для обработки событий ItemAdding или ItemAdded.
Методы ItemAdding или ItemAdded выполняют вызовы удаленного приемника событий.
Надстройка с размещением у поставщика получает значение из настраиваемого свойства профиля пользователя в SharePoint. В этом примере надстройки получено предварительно добавленное настраиваемое свойство классификации профиля пользователя.
Удаленный приемник событий обновляет метаданные в новом документе, подставляя значение настраиваемого свойства профиля пользователя.
Кнопка "Запустить сценарий 1"
Если вы нажимаете кнопку Запустить сценарий 1, надстройка выполняет приведенные ниже действия.
Создание библиотеки документов.
Создание удаленного приемника событий для события ItemAdding.
Примечание.
В этой статье описан приемник событий типа ItemAdding. В основном, приемник событий типа ItemAdding работает лучше, чем ItemAdded. В примере ECM.AutoTagging содержится код для приемников событий обоих типов: ItemAdding и ItemAdded.
Добавление удаленного приемника событий в библиотеку документов.
Эти действия показаны в приведенном ниже коде в методе btnScenario1_Click страницы Default.aspx.cs в проекте ECM.AutoTaggingWeb.
protected void btnScenario1_Click(object sender, EventArgs e)
{
var _libraryToCreate = this.GetLibaryInformationItemAdding();
var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
using (var ctx = spContext.CreateUserClientContextForSPHost())
{
try
{
if(!ctx.Web.ListExists(_libraryToCreate.Title))
{
ScenarioHandler _scenario = new ScenarioHandler();
_scenario.CreateContosoDocumentLibrary(ctx, _libraryToCreate);
}
List _list = ctx.Web.Lists.GetByTitle(_libraryToCreate.Title);
EventReceiverDefinitionCreationInformation _rec = ReceiverHelper.CreateEventReciever(ScenarioHandler.AUTOTAGGING_ITEM_ADDING_RERNAME, EventReceiverType.ItemAdding);
ReceiverHelper.AddEventReceiver(ctx, _list, _rec);
}
catch(Exception _ex)
{
}
}
}
Выполняется вызов метода CreateContosoDocumentLibrary. В приведенном ниже коде в файле ScenarioHandler.cs методы из OfficeDevPnP.Core используются для создания настраиваемой библиотеки документов с настраиваемым типом содержимого. Удален тип содержимого по умолчанию в библиотеке документов.
public void CreateContosoDocumentLibrary(ClientContext ctx, Library library)
{
// Check the fields.
if (!ctx.Web.FieldExistsById(FLD_CLASSIFICATION_ID))
{
ctx.Web.CreateTaxonomyField(FLD_CLASSIFICATION_ID,
FLD_CLASSIFICATION_INTERNAL_NAME,
FLD_CLASSIFICATION_DISPLAY_NAME,
FIELDS_GROUP_NAME,
TAXONOMY_GROUP,
TAXONOMY_TERMSET_CLASSIFICATION_NAME);
}
// Check the content type.
if (!ctx.Web.ContentTypeExistsById(CONTOSODOCUMENT_CT_ID))
{
ctx.Web.CreateContentType(CONTOSODOCUMENT_CT_NAME,
CT_DESC, CONTOSODOCUMENT_CT_ID,
CT_GROUP);
}
// Associate fields to content types.
if (!ctx.Web.FieldExistsByNameInContentType(CONTOSODOCUMENT_CT_NAME, FLD_CLASSIFICATION_INTERNAL_NAME))
{
ctx.Web.AddFieldToContentTypeById(CONTOSODOCUMENT_CT_ID,
FLD_CLASSIFICATION_ID.ToString(),
false);
}
CreateLibrary(ctx, library, CONTOSODOCUMENT_CT_ID);
}
private void CreateLibrary(ClientContext ctx, Library library, string associateContentTypeID)
{
if (!ctx.Web.ListExists(library.Title))
{
ctx.Web.AddList(ListTemplateType.DocumentLibrary, library.Title, false);
List _list = ctx.Web.GetListByTitle(library.Title);
if (!string.IsNullOrEmpty(library.Description))
{
_list.Description = library.Description;
}
if (library.VerisioningEnabled)
{
_list.EnableVersioning = true;
}
_list.ContentTypesEnabled = true;
_list.RemoveContentTypeByName("Document");
_list.Update();
ctx.Web.AddContentTypeToListById(library.Title, associateContentTypeID, true);
ctx.Web.Context.ExecuteQuery();
}
else
{
throw new Exception("A list, survey, discussion board, or document library with the specified title already exists in this website. Please choose another title.");
}
}
После запуска этого кода библиотека документов AutoTaggingSampleItemAdding будет создана в содержании сайта.
Метод CreateEventReciever создает определение приемника событий ItemAdding в проекте ECM.AutoTaggingWeb в файле ReceiverHelper.cs. Папка служб в проекте ECM.AutoTaggingWeb включает веб-службу AutoTaggingService.svc. После публикации проекта ECM.AutoTaggingWeb на вашем веб-сайте Azure эта веб-служба тоже будет развернута на нем. Метод CreateEventReciever назначает веб-службу как удаленный приемник событий в библиотеке документов.
В приведенном ниже коде из метода CreateEventReciever показано, как назначить веб-службу удаленному приемнику событий.
public static EventReceiverDefinitionCreationInformation CreateEventReciever(string receiverName, EventReceiverType type)
{
EventReceiverDefinitionCreationInformation _rer = new EventReceiverDefinitionCreationInformation();
_rer.EventType = type;
_rer.ReceiverName = receiverName;
_rer.ReceiverClass = "ECM.AutoTaggingWeb.Services.AutoTaggingService";
_rer.ReceiverUrl = "https://<Your domain>.azurewebsites.net/Services/AutoTaggingService.svc";
_rer.Synchronization = EventReceiverSynchronization.Synchronous;
return _rer;
}
Приведенный ниже код из метода AddEventReceiver назначает удаленный приемник событий библиотеке документов.
public static void AddEventReceiver(ClientContext ctx, List list, EventReceiverDefinitionCreationInformation eventReceiverInfo)
{
if (!DoesEventReceiverExistByName(ctx, list, eventReceiverInfo.ReceiverName))
{
list.EventReceivers.Add(eventReceiverInfo);
ctx.ExecuteQuery();
}
}
Теперь удаленный приемник событий добавлен в библиотеку документов. Когда вы отправляете документ в библиотеку документов AutoTaggingSampleItemAdding, в нем расставляются теги со значением настраиваемого свойства классификации профиля пользователя.
На приведенном ниже рисунке показано, как просматривать свойства в документе.
На приведенном ниже рисунке показаны метаданные документа с полем классификации.
Метод HandleAutoTaggingItemAdding в файле AutoTaggingService.svc.cs использует метод GetProfilePropertyFor для получения значения свойства классификации профиля пользователя.
public void HandleAutoTaggingItemAdding(SPRemoteEventProperties properties,SPRemoteEventResult result)
{
using (ClientContext ctx = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (ctx != null)
{
var itemProperties = properties.ItemEventProperties;
var _userLoginName = properties.ItemEventProperties.UserLoginName;
var _afterProperites = itemProperties.AfterProperties;
if(!_afterProperites.ContainsKey(ScenarioHandler.FLD_CLASSIFICATION_INTERNAL_NAME))
{
string _classficationToSet = ProfileHelper.GetProfilePropertyFor(ctx, _userLoginName, Constants.UPA_CLASSIFICATION_PROPERTY);
if(!string.IsNullOrEmpty(_classficationToSet))
{
var _formatTaxonomy = AutoTaggingHelper.GetTaxonomyFormat(ctx, _classficationToSet);
result.ChangedItemProperties.Add(ScenarioHandler.FLD_CLASSIFICATION_INTERNAL_NAME, _formatTaxonomy);
}
}
}
}
}
> [! ВАЖНО] > После получения значения **Classification** из метода **GetProfilePropertyFor** значение **Classification** должно быть отформатировано определенным образом, прежде чем его можно будет сохранить в качестве метаданных в документе. Метод **GetTaxonomyFormat** в файле AutoTaggingHelper.cs показывает, как отформатировать значение **Classification**.
public static string GetTaxonomyFormat(ClientContext ctx, string term)
{
if(string.IsNullOrEmpty(term))
{
throw new ArgumentException(string.Format(EXCEPTION_MSG_INVALID_ARG, "term"));
}
string _result = string.Empty;
var _list = ctx.Web.Lists.GetByTitle(TAXONOMY_HIDDEN_LIST_NAME);
CamlQuery _caml = new CamlQuery();
_caml.ViewXml = string.Format(TAXONOMY_CAML_QRY, term);
var _listItemCollection = _list.GetItems(_caml);
ctx.Load(_listItemCollection,
eachItem => eachItem.Include(
item => item,
item => item.Id,
item => item[TAXONOMY_FIELDS_IDFORTERM]));
ctx.ExecuteQuery();
if (_listItemCollection.Count > 0)
{
var _item = _listItemCollection.FirstOrDefault();
var _wssId = _item.Id;
var _termId = _item[TAXONOMY_FIELDS_IDFORTERM].ToString(); ;
_result = string.Format(TAXONOMY_FORMATED_STRING, _wssId, term, _termId);
}
return _result;
}
Кнопка "Удаление сценария событий 1"
При нажатии кнопки Удаление сценария событий 1 запускается приведенный ниже код, который удаляет из библиотеки документов приемник событий.
public static void RemoveEventReceiver(ClientContext ctx, List list, string receiverName)
{
ctx.Load(list, lib => lib.EventReceivers);
ctx.ExecuteQuery();
var _rer = list.EventReceivers.Where(e => e.ReceiverName == receiverName).FirstOrDefault();
if(_rer != null)
{
_rer.DeleteObject();
ctx.ExecuteQuery();
}
}