2

我嘗試使用反射來複制下面的C#代碼:使用反射來設置索引屬性的值

UserProfileManager userProfileManager = new UserProfileManager(ServerContextGoesHere); 
UserProfile userProfile = null; 

userProfile = userProfileManager.GetUserProfile(@"somedomain\someuser"); 

userProfile["PictureUrl"].Value = "This is where I want to update the value using reflection!"; 

userProfile.Commit(); 

使用反射我能得到的一切,除了在那裏我試圖線工作在UserProfile對象上設置「PictureUrl」索引屬性。這索引屬性看起來像這樣使用反編譯器時:

public UserProfileValueCollection this[string strPropName] 

,這裏是使用反射來實現同樣的事情上面我的代碼,看到TODO註釋,我需要設置PictureUrl索引屬性的值:

Assembly userProfileAssembly; 

    var windowsFolderPath = Environment.GetEnvironmentVariable("windir"); 
    var pathToServerAssembly = string.Format(@"{0}\assembly\GAC_MSIL\Microsoft.Office.Server.UserProfiles\14.0.0.0__71e9bce111e9429c\Microsoft.Office.Server.UserProfiles.dll", windowsFolderPath); 

    try 
    { 
     userProfileAssembly = Assembly.LoadFrom(pathToServerAssembly); 
    } 
    catch (FileNotFoundException) 
    { 
     // Assembly wasn't found, so eject. 
     return; 
    } 

    var userProfileManagerClass = userProfileAssembly.GetType("Microsoft.Office.Server.UserProfiles.UserProfileManager"); 
    if (userProfileManagerClass == null) return; 

    var userExistsMethod = userProfileManagerClass.GetMethod("UserExists"); 
    if (userExistsMethod == null) return; 

    var getUserProfileMethod = userProfileManagerClass.GetMethod("GetUserProfile", new[]{typeof(string)}); 
    if (getUserProfileMethod == null) return; 

    var instantiatedUserProfileManagerClass = Activator.CreateInstance(userProfileManagerClass); 
    var result = (bool)userExistsMethod.Invoke(instantiatedUserProfileManagerClass, new object[] { SPContext.Current.Web.CurrentUser.LoginName }); 

    if (!result) return; 

    var userProfileClass = userProfileAssembly.GetType("Microsoft.Office.Server.UserProfiles.UserProfile"); 
    var userProfile = getUserProfileMethod.Invoke(instantiatedUserProfileManagerClass, new object[] { SPContext.Current.Web.CurrentUser.LoginName }); 

    //userProfile["PictureUrl"].Value = userPictureUrl; 
    //TODO: HOW DO I SET THE PICTUREURL PROPERTY USING REFLECTION? 

    var commitMethod = userProfileClass.GetMethod("Commit"); 
    commitMethod.Invoke(userProfile, null); 

由於提前,

瑞安

回答

4

假設你只有在一個UserProfile索引:

PropertyInfo indexProperty = typeof(UserProfile) 
    .GetProperties() 
    .Single(p => p.GetIndexParameters().Length == 1 && p.GetIndexParameters()[0].ParameterType == typeof(string)); 

您現在可以得到的索引值,並設置其Value屬性:

PropertyInfo indexProperty = (from p in t.GetProperties() 
           let indexParams = p.GetIndexParameters() 
           where indexParams.Length == 1 && indexParams[0].ParameterType == typeof(string) 
           select p).Single(); 
+0

object collection = indexProperty.GetValue(userProfile, new object[] { "PictureUrl" }); PropertyInfo valueProperty = collection.GetType().GetProperty("Value"); valueProperty.SetValue(collection, userPictureUrl, null); 

如果你有一個以上的匹配索引屬性,你可以找到它好吧,接近。當我使用最上面的代碼塊時,indexProperty成爲UserProfileValueCollection,它是屬性的正確返回類型。但是,當我嘗試調用SetValue時,我得到「未找到屬性集方法」。這是事實,因爲該財產沒有一套方法。 – Ryan

+0

@Ryan - 對不起,我有點誤解了這個問題。我已經更新了答案,我認爲這應該可以解決您的問題。 – Lee

+0

幹得好,就像冠軍一樣工作。謝謝你的幫助! – Ryan