SharePoint 2013 nos ofrece una nueva interfaz REST para poder realizar un gran número de operaciones desde el lado cliente. En el caso de los perfiles de usuario, tan solo podemos realizar operaciones de consulta, así como actualizar la foto del usuario. En este enlace tenemos más información sobre el uso de la interfaz REST en perfiles de usuario:
http://msdn.microsoft.com/en-us/library/office/jj163800.aspx
En especial, la siguiente tabla es bastante aclarativa al respecto de las operaciones a realizar y las URL REST a utilizar:
Ahora bien, si queremos actualizar el perfil de usuario, tendremos que volver a utilizar el antiguo servicio web userprofileservice.asmx y para ello, nos facilitara bastante la vida el pluggin de jQuery SPServices:
http://spservices.codeplex.com/wikipage?title=$().SPServices&referringTitle=Documentation
El siguiente snippet de código muestra un ejemplo de cómo podemos obtener el perfil de usuario a través de SPServices. Este código se puede incluir en un Script Editor Web Part y previamente deberemos asegurarnos que hemos subido los ficheros JavaScript necesarios a SharePoint, y que los referenciamos dentro del Script Editor Web Part.
1<script type="text/javascript" src="https://lmdev.sharepoint.com/sites/test1/Style%20Library/jquery.SPServices-2013.01.js"></script>2
1function getUserProfile() {2
1 var accountName = $("#user").val();2
1 $().SPServices({2
1 operation: "GetUserProfileByName",2
1 AccountName: accountName,2
1 completefunc: function (data, status) {2
1 var profile = {};2
1 var profileInfo = "";2
1 $(data.responseText).find("PropertyData").each(function (idx, val) {2
1 var $val = $(val);2
1 var name = $val.find("Name").text();2
1 var value = $val.find("Value").text();2
1 profile[name] = value;2
1 profileInfo += name + ": " + value + "<br />";2
1 });2
12
1 $("#result").html(profileInfo);2
1 }2
1 });2
1}2
Y en la siguiente imagen vemos el resultado de la llamada (por facilitar la lectura no están incluidas todas las propiedades):
Y el siguiente snippet, es donde podemos actualizar las propiedades del perfil de usuario:
1function updateProperty() {2
1 var accountName = $("#user").val();2
1 var propertyName = $("#propertyName").val();2
1 var propertyValue = $("#propertyValue").val();2
12
1 var propertyData = "<PropertyData>" +2
1 "<IsPrivacyChanged>false</IsPrivacyChanged>" +2
1 "<IsValueChanged>true</IsValueChanged>" +2
1 "<Name>" + propertyName + "</Name>" +2
1 "<Privacy>NotSet</Privacy>" +2
1 "<Values><ValueData><Value xsi:type=\"xsd:string\">" + propertyValue + "</Value></ValueData></Values>" +2
1 "</PropertyData>";2
12
1 $().SPServices({2
1 operation: "ModifyUserPropertyByAccountName",2
1 accountName: accountName,2
1 newData: propertyData,2
1 completefunc: function (xData, Status) {2
1 var result = $(xData.responseXML);2
1 $("#result").html(result);2
1 }2
1 });2
1}2
Como podemos observar, necesitamos preparar cierto XML, que es utilizado en el SOAP Envelope del servicio web.
Con este código podemos actualizar propiedades del perfil de usuario desde código cliente, pero cabe resaltar que solo se puede actualizar el perfil del usuario logado actualmente, es decir, el usuario que está ejecutando la página. También cabe destacar que no todas las propiedades pueden ser actualizadas, ya que dependerá de si dicha propiedad es sincronizada, en cuyo caso no podrá ser actualizada, o si la propiedad se ha definido para que el usuario no la pueda actualizar.
Con este código ya hemos conseguido una importante mejora respecto a la interfaz REST, pero en muchos escenarios, lo que necesitaremos es actualizar varios perfiles de usuario, no solo el del usuario logado, por ejemplo, en procesos de migraciones de usuarios a SharePoint Online.
En SharePoint Online, tenemos la restricción de que nuestras soluciones deben ser en modo Sandbox, así que no podemos ejecutar código de servidor que utilice la DLL de los User Profile. Sin embargo, podemos invocar el servicio web de los User Profile desde un script PowerShell y hacerlo de tal manera que permite actualizar cualquier perfil de usuario.
El siguiente código es un ejemplo de cómo hacerlo:
1$user = "user@name.onmicrosoft.com" $password = "password" $serviceUrl = "https://name-admin.sharepoint.com/_vti_bin/userprofileservice.asmx"2
1$accountName = "i:0#.f|membership|user@name.onmicrosoft.com"2
12
1$securePassword = ConvertTo-SecureString $password -AsPlainText -Force2
1Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"2
1Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"2
12
1$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user, $securePassword)2
1$userProfileServiceUri = [System.Uri] $serviceUrl2
12
1$authCookie = $credentials.GetAuthenticationCookie($userProfileServiceUri);2
12
1if ($authCookie -eq $null) {2
1 Write-Host "Invalid Authentication cookie" -ForegroundColor Red2
1} else {2
1 Write-Host "SharePoint Online Authentication succesfuly" -ForegroundColor Green2
12
1 $authContainer = New-Object System.Net.CookieContainer2
1 $authContainer.SetCookies($userProfileServiceUri, $authCookie);2
12
1 try {2
1 $svc = New-WebServiceProxy –Uri $serviceUrl'?WSDL' -Namespace WebServiceProxy -Class UserProfile2
1 $svc.CookieContainer = $authContainer2
12
1 Write-Host "Calling UserProfile Service..."2
12
1 #reading a Prperty and printing its value2
1 $prop = $svc.GetUserPropertyByAccountName($accountName, "CellPhone")2
1 $prop.Values2
12
1 #updating a user profile property2
1 $newData = New-Object WebServiceProxy.PropertyData2
1 $newData.Name = "CellPhone"2
1 $valueData = New-Object WebServiceProxy.ValueData2
1 $valueData.Value = "1111 1234 1234"2
1 $newData.Values = @($valueData)2
1 $newData.IsValueChanged = $true2
1 $svc.ModifyUserPropertyByAccountName($accountName, @($newData))2
12
1 } catch [Exception] {2
1 Write-Host $_.Exception.Message2
1 }2
1}2
Lo más destacable del código anterior es:
Y de este modo, seria relativamente sencillo, a partir de un fichero XML, CSV o cualquier origen de datos, migrar información a los perfiles de usuarios de SharePoint Online, cosa que, a día de hoy, no es viable desde el lado cliente (JS o REST), ni desde código de servidor, por ser en modo Sandbox.
Luis Mañez MCPD SharePoint 2010 and Microsoft Active Professional @luismanez http://geeks.ms/blogs/lmanez