Exemplo de suplemento do SharePoint de marcação automática
O exemplo ECM.AutoTagging mostra como usar um suplemento hospedado pelo provedor para marcar automaticamente o conteúdo adicionado a uma biblioteca do SharePoint com dados provenientes de uma propriedade de perfil de usuário personalizada.
Este suplemento usa receptores de evento remotos hospedados em um site do Azure para:
- Criar campos, tipos de conteúdo e bibliotecas de documentos.
- Recuperar o valor de uma propriedade de perfil de usuário personalizada.
- Definir os campos da taxonomia.
Use esta solução se desejar:
- Implementar receptores de evento remotos no SharePoint Online.
- Melhorar os resultados da pesquisa anexando metadados adicionais ao conteúdo quando ele é criado.
- Classificar o conteúdo.
- Modernizar o código antes de migrar para uma versão mais recente do SharePoint e usou receptores de eventos no passado.
Antes de começar
Para começar, faça o download do suplemento de exemplo ECM.AutoTagging no projeto Padrões e Práticas do Desenvolvedor do Office 365 no GitHub.
Observação
The code in this article is provided as-is, without warranty of any kind, either express or implied, including any implied warranties of fitness for a particular purpose, merchantability, or non-infringement.
Antes de executar este exemplo de código, faça o seguinte:
Crie um site do Azure e implante o projeto ECM.AutoTaggingWeb a ele.
Registre o suplemento usando a página Appregnew.aspx no Office 365.
Esse suplemento utiliza permissões somente aplicativo. É preciso atribuir permissões somente aplicativo usando a página AppInv.aspx no Office 365. Copie o seguinte XML do arquivo AppManifest.xml para a caixa XML de Solicitação de Permissão na página AppInv.aspx, conforme mostrado na figura a seguir.
<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>
No projeto ECM.AutoTaggingWeb, no arquivo ReceiverHelper.cs, no método CreateEventReciever, atualize a propriedade ReceiverUrl com o URL do seu site do 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; }
Empacote e implante seu suplemento.
Quando você inicia o suplemento, a página inicial do suplemento hospedado pelo provedor Automarcação de Documentos é exibida, conforme mostrado na figura a seguir. A página inicial mostra algumas etapas adicionais de configuração que você precisa realizar antes de atribuir ou remover receptores de evento.
Usar o exemplo de suplemento ECM.AutoTagging
Esta amostra usa um receptor de evento remoto para marcar automaticamente (adicionar metadados a) documentos adicionados a uma biblioteca de documentos, com dados de uma propriedade de perfil de usuário personalizada.
O fluxo de processo para automarcação de documentos usando o receptor de evento remoto é mostrado na figura a seguir.
Para atribuir metadados ao documento recém-criado na biblioteca de documentos usando um receptor de evento remoto:
Um usuário cria ou carrega novo conteúdo a uma biblioteca de documentos. Um receptor de evento remoto é atribuído para manipular eventos ItemAdding ou ItemAdded nessa biblioteca de documentos.
O método ItemAdding ou ItemAdded faz uma chamada para o receptor de evento remoto.
O suplemento hospedado pelo provedor busca o valor de uma propriedade de perfil de usuário personalizada no serviço de perfil de usuário do SharePoint para esse usuário. Neste exemplo de suplemento, a propriedade de perfil do usuário personalizada de Classificação, adicionada anteriormente, é recuperada.
O receptor de evento remoto atualiza os metadados no novo documento com o valor da propriedade de perfil de usuário personalizada para esse usuário.
Botão Executar Cenário 1
Quando você escolhe o botão Executar Cenário 1, o suplemento faz o seguinte:
Cria uma biblioteca de documentos.
Cria o receptor de evento remoto para o evento ItemAdding.
Observação
Este artigo descreve o tipo de receptor de evento ItemAdding. Em geral, o tipo de receptor de evento ItemAdding tem melhor desempenho do que o tipo de receptor de evento ItemAdded. O exemplo ECM.AutoTagging fornece código para os tipos de receptor de evento ItemAdding e ItemAdded.
Adiciona o receptor de evento remoto à biblioteca de documentos.
O código a seguir, no método btnScenario1_Click da página Default.aspx.cs, no projeto ECM.AutoTaggingWeb, mostra essas etapas.
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)
{
}
}
}
Uma chamada é feita para o método CreateContosoDocumentLibrary. O código a seguir no arquivo ScenarioHandler.cs usa métodos de OfficeDevPnP.Core para criar uma biblioteca de documentos personalizada com um tipo de conteúdo personalizado. O tipo de conteúdo padrão na biblioteca de documentos é removido.
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.");
}
}
Depois que esse código é executado, a biblioteca de documentos AutoTaggingSampleItemAdding é criada no Site Contents4.
No projeto ECM.AutoTaggingWeb, no arquivo ReceiverHelper.cs, o método CreateEventReciever cria a definição do receptor de evento ItemAdding. No projeto ECM.AutoTaggingWeb, a pasta Serviços inclui um serviço Web chamado AutoTaggingService.svc. Quando você publicou o projeto ECM.AutoTaggingWeb no site do Azure, esse serviço Web também foi implantado em seu site. O método CreateEventReciever atribui esse serviço Web como o receptor de evento remoto na biblioteca de documentos.
O código a seguir do método CreateEventReciever mostra como atribuir o serviço Web ao receptor de evento remoto.
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;
}
O código a seguir do método AddEventReceiver atribui o receptor de evento remoto à biblioteca de documentos.
public static void AddEventReceiver(ClientContext ctx, List list, EventReceiverDefinitionCreationInformation eventReceiverInfo)
{
if (!DoesEventReceiverExistByName(ctx, list, eventReceiverInfo.ReceiverName))
{
list.EventReceivers.Add(eventReceiverInfo);
ctx.ExecuteQuery();
}
}
Agora, o receptor de evento remoto está adicionado à biblioteca de documentos. Quando você carrega um documento na biblioteca de documentos AutoTaggingSampleItemAdding , o documento é marcado com o valor da propriedade de perfil de usuário personalizada Classificação para esse usuário.
A figura a seguir mostra como exibir as propriedades de um documento.
A figura a seguir mostra os metadados do documento com o campo Classificação.
O método HandleAutoTaggingItemAdding no arquivo AutoTaggingService.svc.cs usa o método GetProfilePropertyFor para recuperar o valor da propriedade de perfil de usuário Classificação.
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);
}
}
}
}
}
> [! IMPORTANTE] > Depois de recuperar o valor **Classification** do método **GetProfilePropertyFor** , o valor **Classification** deve ser formatado de uma certa maneira antes de poder ser armazenado como metadados no documento. O método **GetTaxonomyFormat** no arquivo AutoTaggingHelper.cs mostra como formatar o valor **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;
}
Botão Remover Cenário de Evento 1
Quando você escolhe o botão Remover Cenário de Evento 1, o código a seguir é executado para remover o receptor de evento da biblioteca de documentos.
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();
}
}