Пример надстройки SharePoint для переноса свойств профиля пользователя
В примере Core.ProfileProperty.Migration показано, как перенести данные профиля пользователя из SharePoint Server в SharePoint Online.
Этот пример включает два консольных приложения. Оба используют веб-службу userprofileservice.asmx для извлечения однозначных и многозначных данных профиля пользователя в XML-файл, а также для импорта извлеченных данных в службу профилей пользователей в SharePoint Online.
Используйте этот пример кода, если вы хотите:
- Извлечение данных профиля пользователя в SharePoint Server.
- Импорт данных профиля пользователя в SharePoint Online.
Подготовка к работе
Чтобы приступить к работе, скачайте пример надстройки Core.ProfileProperty.Migration из проекта шаблоны и методики разработчика Office 365 на сайте GitHub.
Примечание.
Код, приведенный в этой статье, предоставляется "как есть" без какой-либо явной или подразумеваемой гарантии, включая подразумеваемые гарантии пригодности для какой-либо цели, для продажи или гарантии отсутствия нарушения прав иных правообладателей.
Пример кода содержит два проекта:
- Contoso.ProfileProperty.Migration.Extract
- Contoso.ProfileProperty.Migration.Import
Проект Contoso.ProfileProperty.Migration.Extract
Так как в этом примере кода используется серверная объектная модель, убедитесь, что проект выполняется на сервере с установленным Сервером SharePoint Server.
- Используйте учетную запись с разрешениями администратора фермы SharePoint.
- Измените файл App.config, используя сведения о конфигурации, перечисленные в таблице 1.
- Для всех пользователей убедитесь, что свойство профиля пользователя рабочей электронной почты не пусто. Если значение свойства профиля пользователя рабочей электронной почты пусто, процесс извлечения завершится преждевременно.
Этот пример кода извлекает профили пользователей из SharePoint Server 2010. Если вы извлекаете профили пользователей из SharePoint Server 2013, выполните следующие действия.
Откройте контекстное меню (щелкните правой кнопкой мыши) для contoso.ProfileProperty.Migration.Extract>Properties.
В разделе Приложение в поле Целевая платформа выберите платформа .NET Framework 4.
Нажмите кнопку Да, а затем нажмите кнопку Сохранить.
Таблица 1. Параметры конфигурации для файла App.config
Имя параметра конфигурации | Описание | Пример |
---|---|---|
MYSITEHOSTURL | URL-адрес личного сайта в исходной ферме SharePoint Server. | http://my.contoso.com |
PROPERTYSEPARATOR | Символ, используемый для разделения нескольких значений в многозначном свойстве профиля пользователя. | |
USERPROFILESSTORE | Путь к XML-файлу, используемый для записи извлеченных данных профиля пользователя. | C:\temp\ProfileData.xml |
LOGFILE | Путь к XML-файлу, используемый для записи извлеченных данных профиля пользователя. | C:\temp\Extract.log |
ENABLELOGGING | Включает ведение журнала на диске. | Верно |
TESTRUN | Выполняет тестовое извлечение, чтобы убедиться, что параметры конфигурации в App.config верны. | Задайте значение TESTRUN=true , если выполняется тестовое извлечение. Тестовый запуск извлекает только одного пользователя из службы профилей пользователей.Установите значение TESTRUN=false , если вы извлекаете всех пользователей из службы профилей пользователей. |
Проект Contoso.ProfileProperty.Migration.Import
Убедитесь, что профили пользователей существуют в Office 365.
Убедитесь, что рабочий адрес электронной почты пользователя совпадает в локальной среде SharePoint Server и Office 365 службе профилей пользователей.
В файле App.config измените элемент valueпараметра Contoso_ProfileProperty_Migration_Import_UPSvc_UserProfileService , чтобы включить ссылку на службу профилей пользователей в Центре администрирования SharePoint Online, как показано в следующем примере.
<applicationSettings> <Contoso.ProfileProperty.Migration.Import.Properties.Settings> <setting name="Contoso_ProfileProperty_Migration_Import_UPSvc_UserProfileService" serializeAs="String"> <value>https://contoso-admin.sharepoint.com/_vti_bin/userprofileservice.asmx</value> </setting> </Contoso.ProfileProperty.Migration.Import.Properties.Settings> </applicationSettings>
Измените файл App.config с помощью параметров конфигурации, перечисленных в таблице 2.
Табл. 2. параметры конфигурации файла App.config
Имя параметра конфигурации | Описание | Пример |
---|---|---|
tenantName | Это имя вашего клиента. | Если url-адрес клиента — http://contoso.onmicrosoft.com , введите contoso в качестве имени клиента. |
PROPERTYSEPARATOR | Символ, используемый для разделения значений в многозначном свойстве профиля пользователя. | |
USERPROFILESSTORE | XML-файл, используемый для чтения извлеченных данных профиля пользователя. | C:\temp\ProfileData.xml |
LOGFILE | Файл журнала, используемый для ведения журнала событий. | C:\temp\Extract.log |
ENABLELOGGING | Включает ведение журнала на диске. | Верно |
SPOAdminUserName | Имя пользователя Office 365 администратора. | Не применимо. |
SPOAdminPassword | Пароль администратора Office 365. | Не применимо. |
Использование примера надстройки Core.ProfileProperty.Migration
Этот пример кода выполняется как консольное приложение. При выполнении примера кода функция Main в Файле Program.cs выполняет следующие задачи:
- Подключается к узлу личного сайта и использует UserProfileManager для подключения к службе профилей пользователей. UserProfileManager принадлежит Microsoft.Office.Server.UserProfiles.dllсборке .
- Создает список с именем pData для хранения извлеченных данных профиля пользователя.
- Для всех пользователей в службе профилей пользователей она выполняет следующие действия:
- Использует GetSingleValuedProperty для копирования свойств профиля пользователя WorkEmail и AboutMe в объект UserProfileData с именем userData.
- Использует GetMultiValuedProperty для копирования свойства профиля пользователя SPS-Responsibility в userData.
- Использует UserProfileCollection.Save для сериализации userData в XML-файл. XML-файл сохраняется по пути к файлу, указанному в App.config.
static void Main(string[] args)
{
int userCount = 1;
try
{
if (Convert.ToBoolean(ConfigurationManager.AppSettings["TESTRUN"]))
{
LogMessage(string.Format("******** RUNNING IN TEST RUN MODE **********"), LogLevel.Debug);
}
LogMessage(string.Format("Connecting to My Site host: '{0}'...", ConfigurationManager.AppSettings["MYSITEHOSTURL"]), LogLevel.Info);
using (SPSite mySite = new SPSite(ConfigurationManager.AppSettings["MYSITEHOSTURL"]))
{
LogMessage(string.Format("Connecting to My Site host: '{0}'...Done!", ConfigurationManager.AppSettings["MYSITEHOSTURL"]), LogLevel.Info);
LogMessage(string.Format("getting Service Context..."), LogLevel.Info);
SPServiceContext svcContext = SPServiceContext.GetContext(mySite);
LogMessage(string.Format("getting Service Context...Done!"), LogLevel.Info);
LogMessage(string.Format("Connecting to Profile Manager..."), LogLevel.Info);
UserProfileManager profileManager = new UserProfileManager(svcContext);
LogMessage(string.Format("Connecting to Profile Manager...Done!"), LogLevel.Info);
// Size of the List is set to the number of profiles.
List<UserProfileData> pData = new List<UserProfileData>(Convert.ToInt32(profileManager.Count));
// Initialize Serialization Class.
UserProfileCollection ups = new UserProfileCollection();
foreach (UserProfile spUser in profileManager)
{
// Get profile information.
LogMessage(string.Format("processing user '{0}' of {1}...", userCount,profileManager.Count),LogLevel.Info);
UserProfileData userData = new UserProfileData();
userData.UserName = GetSingleValuedProperty(spUser, "WorkEmail");
if (userData.UserName != string.Empty)
{
userData.AboutMe = GetSingleValuedProperty(spUser, "AboutMe");
userData.AskMeAbout = GetMultiValuedProperty(spUser, "SPS-Responsibility");
pData.Add(userData);
// Add to Serialization Class List of Profiles.
ups.ProfileData = pData;
}
LogMessage(string.Format("processing user '{0}' of {1}...Done!", userCount++, profileManager.Count), LogLevel.Info);
// Only process the first item if we are in test mode.
if (Convert.ToBoolean(ConfigurationManager.AppSettings["TESTRUN"]))
{
break;
}
}
// Serialize profiles to disk.
ups.Save();
}
}
catch(Exception ex)
{
LogMessage("Exception trying to get profile properties:\n" + ex.Message, LogLevel.Error);
}
Метод GetSingleValuedProperty использует userprofileservice.asmx для получения свойства профиля пользователя с одним значением. GetSingleValuedProperty выполняет следующие действия, как показано в следующем примере кода:
- Возвращает объект свойства для извлечения данных с помощью spuser[userProperty].
- Возвращает первое значение в UserProfileValueCollection, если значение не равно NULL.
private static string GetSingleValuedProperty(UserProfile spUser,string userProperty)
{
string returnString = string.Empty;
try
{
UserProfileValueCollection propCollection = spUser[userProperty];
if (propCollection[0] != null)
{
returnString = propCollection[0].ToString();
}
else
{
LogMessage(string.Format("User '{0}' does not have a value in property '{1}'", spUser.DisplayName, userProperty), LogLevel.Warning);
}
}
catch
{
LogMessage(string.Format("User '{0}' does not have a value in property '{1}'", spUser.DisplayName, userProperty), LogLevel.Warning);
}
return returnString;
}
Метод GetMultiValuedProperty использует userprofileservice.asmx для получения свойства многозначного профиля пользователя. GetMultiValuedProperty выполняет следующие действия, как показано в следующем примере кода:
- Возвращает объект свойства профиля пользователя для обновления с помощью spuser[userProperty].
- Создает строку значений свойств профиля пользователя, разделенных свойством PROPERTYSEPARATOR , указанным в файле App.config.
private static string GetMultiValuedProperty(UserProfile spUser, string userProperty)
{
StringBuilder sb = new StringBuilder("");
string separator = ConfigurationManager.AppSettings["PROPERTYSEPARATOR"];
string returnString = string.Empty;
try
{
UserProfileValueCollection propCollection = spUser[userProperty];
if (propCollection.Count > 1)
{
for (int i = 0; i < propCollection.Count; i++)
{
if (i == propCollection.Count - 1) { separator = ""; }
sb.AppendFormat("{0}{1}", propCollection[i], separator);
}
}
else if (propCollection.Count == 1)
{
sb.AppendFormat("{0}", propCollection[0]);
}
}
catch
{
LogMessage(string.Format("User '{0}' does not have a value in property '{1}'", spUser.DisplayName, userProperty), LogLevel.Warning);
}
return sb.ToString();
}
Использование примера надстройки Contoso.ProfileProperty.Migration.Import
Этот пример кода выполняется как консольное приложение. При выполнении примера кода метод Main в Файле Program.cs выполняет следующие действия:
- Инициализирует консольное приложение с помощью InitializeConfiguration и InitializeWebService.
- Десериализует XML-файл, содержащий извлеченные данные профиля пользователя.
- Для всех пользователей в XML-файле выполняется следующее:
- Извлекает свойство UserName из XML-файла.
- Использует SetSingleMVProfileProperty , чтобы задать SPS-Responsibility в профиле пользователя.
- Использует SetSingleMVProfileProperty , чтобы задать AboutMe в профиле пользователя.
InitializeWebService подключается к SharePoint Online и задает ссылку на службу профилей пользователей на переменную экземпляра. Другие методы в этом примере кода используют эту переменную экземпляра для записи значений в свойства профиля пользователя. Для администрирования профиля пользователя в этом примере кода используется веб-служба userprofileservice.asmx в Центре администрирования SharePoint Online.
static bool InitializeWebService()
{
try
{
string webServiceExt = "_vti_bin/userprofileservice.asmx";
string adminWebServiceUrl = string.Empty;
if (_profileSiteUrl.EndsWith("/"))
adminWebServiceUrl = _profileSiteUrl + webServiceExt;
else
adminWebServiceUrl = _profileSiteUrl + "/" + webServiceExt;
LogMessage("Initializing SPO web service " + adminWebServiceUrl, LogLevel.Information);
SecureString securePassword = GetSecurePassword(_sPoAuthPasword);
SharePointOnlineCredentials onlineCred = new SharePointOnlineCredentials(_sPoAuthUserName, securePassword);
string authCookie = onlineCred.GetAuthenticationCookie(new Uri(_profileSiteUrl));
CookieContainer authContainer = new CookieContainer();
authContainer.SetCookies(new Uri(_profileSiteUrl), authCookie);
// Setting up the user profile web service.
_userProfileService = new UPSvc.UserProfileService();
_userProfileService.Url = adminWebServiceUrl;
// Assign previously created auth container to admin profile web service.
_userProfileService.CookieContainer = authContainer;
return true;
}
catch (Exception ex)
{
LogMessage("Error initiating connection to profile web service in SPO " + ex.Message, LogLevel.Error);
return false;
}
}
Метод SetSingleMVProfileProperty задает многозначное свойство профиля пользователя, например SPS-Responsibility, выполнив следующие действия:
Разделение PropertyValue на массив строк с именем arrs для хранения значений свойств профиля пользователя. Строка разделяется с помощью параметра конфигурации PROPERTYSEPARATOR , указанного в App.config.
Назначение значений arrs массиву ValueData в службе профилей пользователей.
Создание массива PropertyData в службе профилей пользователей. Имя свойства профиля пользователя и массив ValueData передаются свойствам объекта PropertyData . Этот массив содержит только один элемент, так как будет импортировано только одно многозначное свойство профиля пользователя.
Данные записываются в службу профилей пользователей с помощью команды ModifyUserPropertyByAccountName в веб-службе userprofileservice.asmx в Центре администрирования SharePoint Online. Пользователь, выполняющий этот пример кода, должен быть администратором Office 365.
static void SetSingleMVProfileProperty(string UserName, string PropertyName, string PropertyValue)
{
try
{
string[] arrs = PropertyValue.Split(ConfigurationManager.AppSettings["PROPERTYSEPARATOR"][0]);
UPSvc.ValueData[] vd = new UPSvc.ValueData[arrs.Count()];
for (int i=0;i<=arrs.Count()-1;i++)
{
vd[i] = new UPSvc.ValueData();
vd[i].Value = arrs[i];
}
UPSvc.PropertyData[] data = new UPSvc.PropertyData[1];
data[0] = new UPSvc.PropertyData();
data[0].Name = PropertyName;
data[0].IsValueChanged = true;
data[0].Values = vd;
_userProfileService.ModifyUserPropertyByAccountName(string.Format(@"i:0#.f|membership|{0}", UserName), data);
}
catch (Exception ex)
{
LogMessage("Exception trying to update profile property " + PropertyName + " for user " + UserName + "\n" + ex.Message, LogLevel.Error);
}
}
Метод SetSingleValuedProperty задает однозначные свойства профиля пользователя, например AboutMe. SetSingleValuedProperty реализует тот же метод, что и SetSingleMVProfileProperty, но использует массив ValueData только с одним элементом.
static void SetSingleProfileProperty(string UserName, string PropertyName, string PropertyValue)
{
try
{
UPSvc.PropertyData[] data = new UPSvc.PropertyData[1];
data[0] = new UPSvc.PropertyData();
data[0].Name = PropertyName;
data[0].IsValueChanged = true;
data[0].Values = new UPSvc.ValueData[1];
data[0].Values[0] = new UPSvc.ValueData();
data[0].Values[0].Value = PropertyValue;
_userProfileService.ModifyUserPropertyByAccountName(UserName, data);
}
catch (Exception ex)
{
LogMessage("Exception trying to update profile property " + PropertyName + " for user " + UserName + "\n" + ex.Message, LogLevel.Error);
}
}