Monday, February 8, 2010

Get or set User Profile property using web services

A way of accessing User Profile properties is trough UserProfileManager. If you are an administrator you can read/update/create properties. If you are not admin then you are in trouble. You cannot read or update properties even running with elevated privileges.

A solution is to give all authenticated users the right to edit their profiles:

  • Navigate to Central Admin
  • Navigate to the Shared Service Provider
  • Under User Profiles and My Sites navigate to Personalization services permissions .
  • If the account doesn't already exist, add the account for which your sites App Domain is running under.
  • Grant that user Manage user profiles permission

    Another way is to use web services as described below.

    The idea is to use the UserProfileService.asmx. (http://localhost/_vti_bin/userprofileservice.asmx)

    For this as a first step you must create a web reference to this service and give a name to this reference.

    image

    In my case the property is a string. First instantiate your object:

    public static UPS.UserProfileService ups = new UPS.UserProfileService();



    The code is simple. Please remember that the user under the application pool is running must have the “Manage user profiles” permission.




    public static string GetTheCurrentUserPropertyFromWS()
    {
    String theproperty = String.Empty;
    ups.Url = GetServiceUrl();
    ups.Credentials = System.Net.CredentialCache.DefaultCredentials;

    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
    try
    {
    string userName = System.Web.HttpContext.Current.User.Identity.Name;
    UPS.PropertyData propertyData = GetPropertyFromUser(userName);

    if (propertyData != null && propertyData.Values.Length != 0 && !string.IsNullOrEmpty(propertyData.Values[0].Value as string))
    {
    theproperty = (string)propertyData.Values[0].Value;
    }
    }
    catch (Exception ex)
    {
    throw new NullReferenceException(string.Format("Error: {0} ; User profile for user {1} not found."
    , ex.Message + ups.Url
    , System.Web.HttpContext.Current.User.Identity.Name));
    }
    });

    return theproperty;
    }

    private static bool SetPropertyForCurrentUserFromWS(string propertyAsString)
    {
    bool allOK = true;
    ups.Url = GetServiceUrl();
    ups.Credentials = System.Net.CredentialCache.DefaultCredentials;

    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
    try
    {
    string userName = System.Web.HttpContext.Current.User.Identity.Name;

    UPS.PropertyData propertyData = GetPropertyFromUser(userName);
    if (propertyData != null)
    {
    UpdatePropertyToUser(userName, propertyAsString);
    }
    }
    catch (Exception ex)
    {
    allOK = false;
    throw new NullReferenceException(string.Format("User profile for user {0} not found."
    , System.Web.HttpContext.Current.User.Identity.Name + ups.Url));
    }
    });

    return allOK;
    }

    private static UPS.PropertyData GetPropertyFromUser(string userName)
    {
    UPS.PropertyData returnpropertyData = null;
    UPS.PropertyData[] userpropertydata = ups.GetUserProfileByName(userName);
    foreach (UPS.PropertyData pd in userpropertydata)
    {
    if (pd.Name == "MyPropertyName")
    {
    returnpropertyData = (UPS.PropertyData)pd;
    break;
    }
    }
    return returnpropertyData;
    }

    private static void UpdatePropertyToUser(string userName, string result)
    {
    // the property already exist - must only update
    UPS.PropertyData[] newdata = new UPS.PropertyData[1];
    newdata[0] = new UPS.PropertyData();
    newdata[0].Name = "MyPropertyName";
    newdata[0].Values = new UPS.ValueData[1];
    newdata[0].Values[0] = new UPS.ValueData();
    newdata[0].Values[0].Value = result;
    newdata[0].IsValueChanged = true;
    ups.ModifyUserPropertyByAccountName(userName, newdata);
    }

    private static string GetServiceUrl()
    {
    StringBuilder sb = new StringBuilder();

    string suffixUrl = "_vti_bin/userprofileservice.asmx";
    Uri theUri = new Uri(SPContext.Current.Site.Url);
    string prefixUrl = theUri.AbsoluteUri;
    if (theUri.AbsolutePath != @"/")
    {
    prefixUrl = prefixUrl.Replace(theUri.AbsolutePath, "");
    sb.Append(prefixUrl).Append(@"/").Append(suffixUrl);
    }
    else
    {
    sb.Append(prefixUrl).Append(suffixUrl);
    }

    return sb.ToString();
    }





    Now you can get or set values for user properties. Remember that the property must be already created. You cannot create one using a web service. 






  • 1 comment: