Работа с социальными тегами в SharePoint 2010
Исходная статья опубликована в четверг, 29 сентября 2011 г.
ПРИМЕЧАНИЕ. Загрузите приложение с документом Word в удобном для чтения формате.
Недавно я получил интересный запрос — нужно было выполнить миграцию социальных тегов между двумя разными фермами. Это можно сделать несколькими неожиданными способами, в то время как некоторые способы выглядят заманчиво, но их оказывается недостаточно.
Я лично протестировал получение тегов без какого-либо "реального" олицетворения. У меня это работало, но я не могу гарантировать, что это будет работать во всех случаях, поскольку я входил как администратор приложения профилей пользователей (UPA). Если в вашем случае это не работает, можно воспользоваться методом олицетворения, который я буду описывать ниже. Чтобы получить теги для пользователя, я просто попытался создать контекст SPSite от лица этого пользователя, а затем создать все объекты контекста, необходимые для извлечения тегов этого пользователя, следующим образом.
SPUserToken sut = null;
//get the user token for user first so we can
//use that to get a site context as that user
using (SPSite userSite = new SPSite(UrlTxt.Text))
{
using (SPWeb rootWeb = userSite.RootWeb)
{
SPUser socialUser =
rootWeb.EnsureUser(AccountTxt.Text);
sut = socialUser.UserToken;
}
}
//now get the site as that user – NOTE: these are
//all class scoped variables
using (SPSite newSite = new SPSite(UrlTxt.Text, sut))
{
sc = SPServiceContext.GetContext(newSite);
stm = new SocialTagManager(sc);
upm = new UserProfileManager(sc);
up = upm.GetUserProfile(AccountTxt.Text);
}
После получения объектов контекста, созданных от имени текущего пользователя, довольно легко получить и теги для этого пользователя:
SocialTag[] tags = stm.GetTags(up);
TagLst.Items.Clear();
foreach (SocialTag tag in tags)
{
TagLst.Items.Add(tag.Term.Name + " - " + tag.Url.ToString());
}
Эта часть была довольно понятной и простой. К сожалению, создать тег для другого пользователя было не так просто. В SocialTagManager имеется метод AddTag, но в отличие от метода GetTags он не предоставляет перегрузку, включающую UserProfile. Это серьезное упущение, и использование контекста пользователя, переданного в новый конструктор SPSite, не помогает. В результате для этого вам придется использовать олицетворение. В данном случае я просто повторил подход, описанный в статье https://blogs.msdn.com/b/sharepoint_ru/archive/2011/10/07/saml-sharepoint-wcf-windows-sql-server.aspxdelegation-to-access-sql-server.aspx. Я настроил CTWTS таким образом, чтобы я мог (поскольку это мое приложение, работавшее в моем контексте пользователя) олицетворять пользователей самостоятельно. Подробные сведения о том, как это сделать, можно найти здесь: https://msdn.microsoft.com/en-us/library/ee517258.aspx.
Итак, в соответствии с этим подходом, вот как я приступил к олицетворению:
//start the impersonation
//create the WindowsIdentity for impersonation
WindowsIdentity wid = null;
try
{
wid = S4UClient.UpnLogon(EmailTxt.Text);
}
catch (SecurityAccessDeniedException adEx)
{
MessageBox.Show("Could not map the Email to " +
"a valid windows identity: " + adEx.Message);
}
//see if we were able to successfully login
if (wid != null)
{
using (WindowsImpersonationContext ctx = wid.Impersonate())
{
//code goes here to add a new tag
}
}
else
{
MessageBox.Show("Couldn't impersonate user - can't add tag.");
}
Сам по себе код олицетворения не слишком сложный — вам только потребуется адрес электронной почты пользователя (который вы, скорее всего, можете получить из его профиля UserProfile, извлекаемого этим кодом). Вам также потребуется запустить CTWTS, который устанавливается на каждом сервере SharePoint, и этот код необходимо запускать на сервере SharePoint, поскольку он использует объектную модель. Еще раз подчеркну, что это не должно вызвать особых затруднений.
Наконец, чтобы добавить новый тег для пользователя, придется прыгнуть через несколько колец, но это достаточно понятная процедура. Вот как этот код выглядит:
//this is the code that gets the SPSite, SPServiceContext, etc
GetServiceContext();
//work with the taxonomy classes so we
//can reuse any existing term, or create a
//new one if it doesn't exist
TaxonomySession txs = stm.TaxonomySession;
TermStore ts = txs.DefaultKeywordsTermStore;
TermCollection terms =
ts.KeywordsTermSet.GetTerms(TagTxt.Text,
ts.DefaultLanguage, true);
Term t = null;
if (terms.Count == 0)
{
t = ts.KeywordsTermSet.CreateTerm(TagTxt.Text,
ts.DefaultLanguage);
ts.CommitAll();
}
else
t = terms[0];
//add the tag
stm.AddTag(new Uri(TagUrlTxt.Text), t);
Итак, что же здесь происходит? Мы просто заглядываем в банк таксономии, чтобы найти добавляемый тег. Если мы его там находим, то используем этот термин, если нет — то создаем его и добавляем в банк терминов. Затем мы добавляем этот термин и связываем его с URL-адресом, и он будет добавлен в теги этого пользователя.
В целом и код, и метод довольно просты. Основная задача состоит в том, чтобы обойти невозможность указания пользователя, которому следует добавить тег. Эту часть за нас выполняет код олицетворения и CTWTS, не требуя пароля для каждого пользователя. Исходный код для этого проекта прилагается к данной статье.
Это локализованная запись блога. Исходная статья находится по ссылке Working with Social Tags in SharePoint 2010