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:
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.
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.
this help me ! thx !
ReplyDelete