c# - 为什么自定义 SharePoint 计时器作业只能处理列表中的一半项目?
问题描述
我们有一个计时器作业,它检查 SharePoint 用户配置文件服务中的用户位置和职位,然后使用关联的经理更新办公室页面库的元数据。我们最近更新了逻辑,在我们的 QA 环境中发布并运行了它,有些页面确实得到了更新,有些则没有。尽管在 User Profile Service 中有经理,但大约有一半没有变化。为什么相同的代码会在一半的页面上失败?
该列表包含办公室、经理等列。代码在每个配置文件中循环,如果用户在其配置文件中具有标题“经理”和办公室“西雅图”,它会搜索库并将该用户设置为经理并发布这页纸。所有页面都基于一个共同的内容类型。
尝试清除所有页面上的所有经理字段,其中一半更新。失败的用户确实有用户配置文件,我可以手动设置管理器。什么可能导致它仅在某些页面上失败?
这是代码。在 GetOfficeManagers 方法中,我循环遍历它们两次,一次是设置处于培训中的经理,然后用完整的经理覆盖它们(如果存在的话)(有些只有经理在培训中)。这是我对代码所做的更改。
//using statements snipped for brevity
namespace RC.SharePoint.Portal.TimerJobs
{
public class SyncOfficeLocationService: SPJobDefinition
{
#region CONSTANTS
public const string JOB_NAME = "World Office Location Synchronization Service";
public const string TIMER_JOB_META_DATA = "TimerJobMetaData";
private const string PAGES_LIBRARY = "Pages";
private const string USER_PROFILE_FIELD_OFFICE = "Office";
private const string USER_PROFILE_FIELD_TITLE = "Title";
private const string USER_PROFILE_FIELD_DEPT = "Department";
private const string USER_PROFILE_DEPT_REST_OP = "Office Operations";
private const string Office_PROFILE_CONTENT_TYPE = "Office Profile";
private const string Office_SITE_NAME = "rest";
private struct Designations
{
public const string General_Manager = "General Manager";
public const string General_Manager_In_Training = "General Manager in Training";
public const string ManagingPartner = "Managing Partner";
public const string ManagingPartner_In_Training = "Managing Partner in Training";
public const string OperationsManager = "Operations Manager";
public const string OperationsManager_In_Training = "Operations Manager in Training";
public const string ShiftManager = "Shift Manager";
public const string ShiftManager_In_Training = "Shift Manager in Training";
}
private struct Pages
{
public const string Title = "Title";
public const string ContentType = "ContentType";
public const string Name = "Name";
public const string NameInt = "FileLeafRef";
public const string GeneralManager = "General Manager";
public const string GeneralManagerInt = "RC_RestProfile_GeneralManager";
public const string ManagingPartner = "Managing Partner";
public const string ManagingPartnerInt = "RC_RestProfile_ManagingPartner";
public const string OperationsManager = "Operations Manager";
public const string OperationsManagerInt = "RC_RestProfile_OperationsManager";
public const string ShiftManager1 = "Shift Manager 1";
public const string ShiftManager1Int = "RC_RestProfile_ShiftManager1";
public const string ShiftManager2 = "Shift Manager 2";
public const string ShiftManager2Int = "RC_RestProfile_ShiftManager2";
//snipped for space
}
#endregion
#region CONSTRUCTORS
public SyncOfficeLocationService()
: base()
{
}
public SyncOfficeLocationService(string jobName, SPService service, SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType)
{
}
public SyncOfficeLocationService(string jobName, SPWebApplication webApplication)
: base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
{
this.Title = jobName;
}
#endregion
#region METHODS
protected override bool HasAdditionalUpdateAccess()
{
return true;
}
public override void Execute(Guid targetInstanceId)
{
try
{
//Read settings from Hierarchical object store
TimerJobMetaData settings = this.WebApplication.GetChild<TimerJobMetaData>(TIMER_JOB_META_DATA);
using (SPSite site = new SPSite(settings.SiteUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Medium, EventSeverity.Information), TraceSeverity.Medium, string.Format("Timer Service started for SharePoint portal: {0}", web.Url), "");
List<OfficeLocation> Offices = GetOfficeManagers(site);
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Medium, EventSeverity.Information), TraceSeverity.Medium, "User profile service parsed successfully. " + Offices.Count.ToString() + " Offices found.", "");
SyncOfficeManagers(web.Webs[Office_SITE_NAME], Offices);
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Medium, EventSeverity.Information), TraceSeverity.Medium, string.Format("Timer Service finished for SharePoint portal: {0}", web.Url), "");
}
}
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
}
private Dictionary<string, string> GetUserProfiles(SPSite site)
{
Dictionary<string, string> users = new Dictionary<string, string>();
try
{
SPServiceContext serverContext = SPServiceContext.GetContext(site);
UserProfileManager profileManager = new UserProfileManager(serverContext);
IEnumerator userProfiles = profileManager.GetEnumerator();
while (userProfiles.MoveNext())
{
UserProfile userProfile = (UserProfile)userProfiles.Current;
if (userProfile[USER_PROFILE_FIELD_TITLE] != null && userProfile[USER_PROFILE_FIELD_TITLE].Value != null && userProfile[USER_PROFILE_FIELD_TITLE].Value.ToString().Equals(Designations.General_Manager))
{
if (userProfile[USER_PROFILE_FIELD_OFFICE] != null && userProfile[USER_PROFILE_FIELD_OFFICE].Value != null)
{
string key = string.Format("{0}.aspx", userProfile[USER_PROFILE_FIELD_OFFICE].Value.ToString().Replace("RC ", "C"));
if (!users.ContainsKey(key))
users.Add(key, userProfile.AccountName);
}
}
}
}
catch(Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
return users;
}
private void SyncOffices(SPWeb web, Dictionary<string, string> users)
{
try
{
SPDocumentLibrary pagesLib = web.Lists[PAGES_LIBRARY] as SPDocumentLibrary;
SPClaimProviderManager cpm = SPClaimProviderManager.Local;
SPWeb rootWeb = web.Site.RootWeb;
var query = new SPQuery();
query.Query = string.Format(@"<Where><Eq><FieldRef Name=""{0}"" /><Value Type=""Text"">{1}</Value></Eq></Where>", Pages.ContentType, Office_PROFILE_CONTENT_TYPE);
query.ViewFields = string.Format(@"<FieldRef Name=""{0}"" /><FieldRef Name=""{1}"" /><FieldRef Name=""{2}"" /><FieldRef Name=""{3}"" />", Pages.ContentType, Pages.Title, Pages.NameInt, Pages.GeneralManagerInt);
query.ViewAttributes = @"Scope=""Recursive""";
query.RowLimit = 0;
SPListItemCollection items = pagesLib.GetItems(query);
foreach (SPListItem item in items)
{
string fileName = item[Pages.Name].ToString();
if (users.ContainsKey(fileName))
{
string mgr = string.Empty;
if (item[Pages.GeneralManager] != null)
{
mgr = new SPFieldUserValue(web, item[Pages.GeneralManager].ToString()).User.LoginName;
}
if (!mgr.EndsWith(users[fileName]))
{
SPFile file = item.File;
if (file.CheckOutType == SPFile.SPCheckOutType.None)
file.CheckOut();
SPClaim userClaim = cpm.ConvertIdentifierToClaim(users[fileName], SPIdentifierTypes.WindowsSamAccountName);
SPUser newMgr = rootWeb.EnsureUser(userClaim.ToEncodedString());
item[Pages.GeneralManager] = new SPFieldUserValue(web, newMgr.ID, newMgr.Name);
item.Update();
file.CheckIn("Automatically checked-in by SharePoint Synchronization Timer Job");
file.Publish("Automatically published by SharePoint Synchronization Timer Job");
}
}
}
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
}
private List<OfficeLocation> GetOfficeManagers(SPSite site)
{
List<OfficeLocation> Offices = new List<OfficeLocation>();
try
{
SPServiceContext serverContext = SPServiceContext.GetContext(site);
UserProfileManager profileManager = new UserProfileManager(serverContext);
IEnumerator userProfiles = profileManager.GetEnumerator();
while (userProfiles.MoveNext())
{
UserProfile userProfile = (UserProfile)userProfiles.Current;
//Check for department name, it must be "Office Operations"
if (userProfile[USER_PROFILE_FIELD_DEPT] != null && userProfile[USER_PROFILE_FIELD_DEPT].Value != null && userProfile[USER_PROFILE_FIELD_DEPT].Value.ToString().Equals(USER_PROFILE_DEPT_REST_OP))
{
//Check for Office location, it must not be null or empty
if (userProfile[USER_PROFILE_FIELD_OFFICE] != null && userProfile[USER_PROFILE_FIELD_OFFICE].Value != null)
{
string location = userProfile[USER_PROFILE_FIELD_OFFICE].Value.ToString();
OfficeLocation Office = FindOffice(Offices, location);
if (Office == null)
{
Office = new OfficeLocation();
Office.Location = location;
Office.PageName = string.Format("{0}.aspx", location.Replace("RC ", "C"));
Offices.Add(Office);
}
if (userProfile[USER_PROFILE_FIELD_TITLE] != null && userProfile[USER_PROFILE_FIELD_TITLE].Value != null)
{
string designation = userProfile[USER_PROFILE_FIELD_TITLE].Value.ToString();
switch(designation)
{
case Designations.General_Manager_In_Training:
Office.GeneralManager = userProfile.AccountName.ToLower();
break;
case Designations.ManagingPartner_In_Training:
Office.ManagingPartner = userProfile.AccountName.ToLower();
break;
case Designations.OperationsManager_In_Training:
Office.OperationsManager = userProfile.AccountName.ToLower();
break;
case Designations.ShiftManager:
Office.ShiftManagers.Add(userProfile.AccountName.ToLower());
break;
}
}
}
}
}
IEnumerator userProfiles2 = profileManager.GetEnumerator();
while (userProfiles2.MoveNext())
{
UserProfile userProfile = (UserProfile)userProfiles2.Current;
//Check for department name, it must be "Office Operations"
if (userProfile[USER_PROFILE_FIELD_DEPT] != null && userProfile[USER_PROFILE_FIELD_DEPT].Value != null && userProfile[USER_PROFILE_FIELD_DEPT].Value.ToString().Equals(USER_PROFILE_DEPT_REST_OP))
{
//Check for Office location, it must not be null or empty
if (userProfile[USER_PROFILE_FIELD_OFFICE] != null && userProfile[USER_PROFILE_FIELD_OFFICE].Value != null)
{
string location = userProfile[USER_PROFILE_FIELD_OFFICE].Value.ToString();
OfficeLocation Office = FindOffice(Offices, location);
if (Office == null)
{
Office = new OfficeLocation();
Office.Location = location;
Office.PageName = string.Format("{0}.aspx", location.Replace("RC ", "C"));
Offices.Add(Office);
}
if (userProfile[USER_PROFILE_FIELD_TITLE] != null && userProfile[USER_PROFILE_FIELD_TITLE].Value != null)
{
string designation = userProfile[USER_PROFILE_FIELD_TITLE].Value.ToString();
switch (designation)
{
case Designations.General_Manager:
Office.GeneralManager = userProfile.AccountName.ToLower();
break;
case Designations.ManagingPartner:
Office.ManagingPartner = userProfile.AccountName.ToLower();
break;
case Designations.OperationsManager:
Office.OperationsManager = userProfile.AccountName.ToLower();
break;
case Designations.ShiftManager_In_Training:
Office.ShiftManagers.Add(userProfile.AccountName.ToLower());
break;
}
}
}
}
}
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
return Offices;
}
private void SyncOfficeManagers(SPWeb web, List<OfficeLocation> Offices)
{
try
{
SPDocumentLibrary pagesLib = web.Lists[PAGES_LIBRARY] as SPDocumentLibrary;
SPClaimProviderManager cpm = SPClaimProviderManager.Local;
SPWeb rootWeb = web.Site.RootWeb;
SPClaim userClaim = null;
SPUser newMgr = null;
var query = new SPQuery();
query.Query = string.Format(@"<Where><Eq><FieldRef Name=""{0}"" /><Value Type=""Text"">{1}</Value></Eq></Where>", Pages.ContentType, Office_PROFILE_CONTENT_TYPE);
//query.ViewFields = string.Format(@"<FieldRef Name=""{0}"" /><FieldRef Name=""{1}"" /><FieldRef Name=""{2}"" /><FieldRef Name=""{3}"" />", Pages.ContentType, Pages.Title, Pages.NameInt, Pages.GeneralManagerInt);
query.ViewAttributes = @"Scope=""Recursive""";
query.RowLimit = 0;
SPListItemCollection items = pagesLib.GetItems(query);
foreach (SPListItem item in items)
{
string pageName = item[Pages.Name].ToString();
OfficeLocation Office = FindOfficeByPageName(Offices, pageName);
if (Office != null)
{
bool updateItem = false;
string mgr = string.Empty;
#region General Manager
if (item[Pages.GeneralManager] != null)
{
mgr = new SPFieldUserValue(web, item[Pages.GeneralManager].ToString()).User.LoginName;
}
if (string.IsNullOrEmpty(Office.GeneralManager) && !string.IsNullOrEmpty(mgr))
{
item[Pages.GeneralManager] = null;
updateItem = true;
}
else if (!mgr.ToLower().EndsWith(Office.GeneralManager))
{
userClaim = cpm.ConvertIdentifierToClaim(Office.GeneralManager, SPIdentifierTypes.WindowsSamAccountName);
newMgr = rootWeb.EnsureUser(userClaim.ToEncodedString());
item[Pages.GeneralManager] = new SPFieldUserValue(web, newMgr.ID, newMgr.Name);
updateItem = true;
}
#endregion
#region Managing Partner
mgr = string.Empty;
if (item[Pages.ManagingPartner] != null)
{
mgr = new SPFieldUserValue(web, item[Pages.ManagingPartner].ToString()).User.LoginName;
}
if (string.IsNullOrEmpty(Office.ManagingPartner) && !string.IsNullOrEmpty(mgr))
{
item[Pages.ManagingPartner] = null;
updateItem = true;
}
else if (!mgr.ToLower().EndsWith(Office.ManagingPartner))
{
userClaim = cpm.ConvertIdentifierToClaim(Office.ManagingPartner, SPIdentifierTypes.WindowsSamAccountName);
newMgr = rootWeb.EnsureUser(userClaim.ToEncodedString());
item[Pages.ManagingPartner] = new SPFieldUserValue(web, newMgr.ID, newMgr.Name);
updateItem = true;
}
#endregion
#region Operations Manager
mgr = string.Empty;
if (item[Pages.OperationsManager] != null)
{
mgr = new SPFieldUserValue(web, item[Pages.OperationsManager].ToString()).User.LoginName;
}
if (string.IsNullOrEmpty(Office.OperationsManager) && !string.IsNullOrEmpty(mgr))
{
item[Pages.OperationsManager] = null;
updateItem = true;
}
else if (!mgr.ToLower().EndsWith(Office.OperationsManager))
{
userClaim = cpm.ConvertIdentifierToClaim(Office.OperationsManager, SPIdentifierTypes.WindowsSamAccountName);
newMgr = rootWeb.EnsureUser(userClaim.ToEncodedString());
item[Pages.OperationsManager] = new SPFieldUserValue(web, newMgr.ID, newMgr.Name);
updateItem = true;
}
#endregion
#region Shift Managers
for (int count = 0; count < 6; count++)
{
string shiftMgr = string.Empty;
if (Office.ShiftManagers.Count > count)
shiftMgr = Office.ShiftManagers[count];
string shiftMgrFieldName = GetShiftManagerFieldName(count + 1);
if (!string.IsNullOrEmpty(shiftMgrFieldName))
{
mgr = string.Empty;
if (item[shiftMgrFieldName] != null)
{
mgr = new SPFieldUserValue(web, item[shiftMgrFieldName].ToString()).User.LoginName;
}
if (string.IsNullOrEmpty(shiftMgr) && !string.IsNullOrEmpty(mgr))
{
item[shiftMgrFieldName] = null;
updateItem = true;
}
else if (!mgr.ToLower().EndsWith(shiftMgr))
{
userClaim = cpm.ConvertIdentifierToClaim(shiftMgr, SPIdentifierTypes.WindowsSamAccountName);
newMgr = rootWeb.EnsureUser(userClaim.ToEncodedString());
item[shiftMgrFieldName] = new SPFieldUserValue(web, newMgr.ID, newMgr.Name);
updateItem = true;
}
}
}
#endregion
if (updateItem)
{
SPFile file = item.File;
if (file.CheckOutType == SPFile.SPCheckOutType.None)
file.CheckOut();
item.Update();
file.CheckIn("Automatically checked-in by SharePoint Synchronization Timer Job");
file.Publish("Automatically published by SharePoint Synchronization Timer Job");
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Medium, EventSeverity.Information), TraceSeverity.Medium, string.Format("Page {0} updated.", pageName), "");
}
}
}
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(1, new SPDiagnosticsCategory("SharePoint Synchronization Timer Job", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
}
private string GetShiftManagerFieldName(int count)
{
switch(count)
{
case 1:
return Pages.ShiftManager1;
case 2:
return Pages.ShiftManager2;
//snipped for brevity - goes to 6
}
return string.Empty;
}
private static OfficeLocation FindOffice(List<OfficeLocation> Offices, string location)
{
OfficeLocation Office = Offices.Find(
delegate(OfficeLocation r)
{
return r.Location.Equals(location);
}
);
return Office;
}
private static OfficeLocation FindOfficeByPageName(List<OfficeLocation> Offices, string pageName)
{
OfficeLocation Office = Offices.Find(
delegate(OfficeLocation r)
{
return r.PageName.Equals(pageName);
}
);
//Handle pages with name "C01.aspx"
if (Office == null)
{
if (pageName.IndexOf("0") != 1)
{
pageName = pageName.Insert(1, "0");
Office = Offices.Find(
delegate(OfficeLocation r)
{
return r.PageName.Equals(pageName);
}
);
}
}
//Handle pages with name "C1.aspx"
if (Office == null)
{
if (pageName.IndexOf("0") != 2)
{
pageName = pageName.Insert(1, "0");
Office = Offices.Find(
delegate(OfficeLocation r)
{
return r.PageName.Equals(pageName);
}
);
}
}
return Office;
}
#endregion
}
public class OfficeLocation
{
public OfficeLocation()
{
Location = string.Empty;
PageName = string.Empty;
GeneralManager = string.Empty;
ManagingPartner = string.Empty;
OperationsManager = string.Empty;
ShiftManagers = new StringCollection();
}
public string Location { get; set; }
public string PageName { get; set; }
public string GeneralManager { get; set; }
public string ManagingPartner { get; set; }
public string OperationsManager { get; set; }
public StringCollection ShiftManagers { get; set; }
}
public class TimerJobMetaData : SPPersistedObject
{
[Persisted]
public string SiteUrl;
public TimerJobMetaData() { }
public TimerJobMetaData(string name, SPPersistedObject parent, Guid Id)
: base(name, parent, Id)
{ }
}
}
解决方案
推荐阅读
- java - 在 XSLT 中注入命名空间
- python - Pyqt5 deleteLater() VS sip.delete()
- html - nth-child 没有在表格中正确应用背景颜色
- reactjs - 谁能解释一下 React 中的这个 setState 调用
- python - 按组反转元素的顺序
- go - Go 中的替代导入语法
- wordpress-theming - WordPress 不显示帖子的详细信息
- python - 点击使用 Beautifulsoup/Selenium 的链接
- javascript - 为什么浏览器看不到本地存储元素的值?
- android - 在 RxJava 上链接调用