我正在使用EWS托管API将数据从Exchange提取到sharePoint应用程序。我使用GetUserAvailability方法来检索信息。不幸的是,即使在工作时间以外,交换时间也是如此。当组织者在EST并且参加者在澳大利亚时间时,问题更加明显。他们的工作时间都设置在当地时间的当地时间上午8点到下午5点。所以当搜索一个共同的时间时,不应该有任何重叠,但交换会在考虑组织者时区的情况下返回时间,这不是预期的结果。以下代码仅供参考。
public List<Week> RefineParams(string strLoginID, string strUserIds, DateTime StartTime, DateTime EndTime, int intNumberOfWeeks, int intMeetDur, bool includeNonBusHr, string strTimeZoneOffSet, string upn)
{
List<Week> weeks = null;
try
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "RefineParams started");
ExchangeService _ews = null;
string strTimeZoneID = GetTimeZoneStringFromOffset(strTimeZoneOffSet);
_ews = new ExchangeService(ExchangeVersion.Exchange2010, TimeZoneInfo.FindSystemTimeZoneById(strTimeZoneID));
// Override certificate check (due to lab environment using self-signed certs)
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
string name = WindowsIdentity.GetCurrent().Name;
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "EWS Credential " + System.Security.Principal.WindowsIdentity.GetCurrent().Name + "Authentication Type " + System.Security.Principal.WindowsIdentity.GetCurrent().AuthenticationType);
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//IClaimsIdentity identity = (ClaimsIdentity)Thread.CurrentPrincipal.Identity;
//string upn = null;
//foreach (Claim claim in identity.Claims)
//{
// if (StringComparer.Ordinal.Equals(ClaimTypes.Upn, claim.ClaimType))
// {
// upn = claim.Value;
// KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), " UPN Value= " + upn + " for user: " + name);
// }
//}
// Perform the UPN logon through the c2WTS.
WindowsIdentity windowsIdentity = null;
if (!String.IsNullOrEmpty(upn))
{
try
{
windowsIdentity = S4UClient.UpnLogon(upn);
if (windowsIdentity != null)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Windows indentity created for UPN: " + upn);
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Failed to create Windows indentity");
}
}
catch (SecurityAccessDeniedException)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Could not map the upn claim to a valid windows identity.name : " + name);
}
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Refine Params: No UPN claim found");
throw new Exception("No UPN claim found");
}
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Before impeosonation Thread.Current.Name: " + Thread.CurrentPrincipal.Identity.Name);
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Before impeosonation WindowsIdentity.GetCurrent().Name: " + WindowsIdentity.GetCurrent().Name);
string strOrganizer = GetEmailForLoginName(strLoginID);
string strAttendeeEmails = GetEmailForUserID(strUserIds);
using (WindowsImpersonationContext ctxt = windowsIdentity.Impersonate())
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "After impeosonation Thread.Current.Name: " + Thread.CurrentPrincipal.Identity.Name);
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "After impeosonation WindowsIdentity.GetCurrent().Name: " + WindowsIdentity.GetCurrent().Name);
string strEWSServiceURL = ConfigurationManager.AppSettings.Get("EWSServiceURL");
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "EWS URL " + strEWSServiceURL);
_ews.Url = new Uri(strEWSServiceURL);
// Create a list of attendees.
List<AttendeeInfo> attendees = new List<AttendeeInfo>();
string[] arrUserID = null;
strUserIds = strUserIds.Trim(',');
arrUserID = strAttendeeEmails.Split(',');
attendees.Add(new AttendeeInfo()
{
//email address.
SmtpAddress = strOrganizer,
AttendeeType = MeetingAttendeeType.Organizer,
ExcludeConflicts = true
});
for (int i = 0; i < arrUserID.Length; i++)
{
if (!string.IsNullOrWhiteSpace(arrUserID[i]) && arrUserID[i].Contains("@"))
{
attendees.Add(new AttendeeInfo()
{
//email address.
SmtpAddress = Convert.ToString(arrUserID[i]),
AttendeeType = MeetingAttendeeType.Required,
ExcludeConflicts = true
});
}
}
foreach (AttendeeInfo aa in attendees)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Attendee " + aa.SmtpAddress + "Attendeee type "+ aa.AttendeeType);
}
// Specify suggested meeting time options.
AvailabilityOptions meetingOptions = new AvailabilityOptions();
meetingOptions.MeetingDuration = intMeetDur;
if (includeNonBusHr)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Viewing business hours "+includeNonBusHr);
meetingOptions.MaximumNonWorkHoursSuggestionsPerDay = 48;
meetingOptions.MaximumSuggestionsPerDay = 48;
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Viewing business hours " + includeNonBusHr);
meetingOptions.MaximumNonWorkHoursSuggestionsPerDay = 0;
meetingOptions.MaximumSuggestionsPerDay = Convert.ToInt32(ConfigurationManager.AppSettings.Get("MaximumSuggestionsPerDay"));
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "MaximumSuggestionsPerDay " + meetingOptions.MaximumSuggestionsPerDay);
}
meetingOptions.GoodSuggestionThreshold = Convert.ToInt32(ConfigurationManager.AppSettings.Get("GoodSuggestionThreshold"));
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "MaximumSuggestionsPerDay " + meetingOptions.GoodSuggestionThreshold);
meetingOptions.MinimumSuggestionQuality = SuggestionQuality.Good;
EndTime = EndTime.AddDays(1);
meetingOptions.DetailedSuggestionsWindow = new TimeWindow(StartTime, EndTime);
meetingOptions.RequestedFreeBusyView = FreeBusyViewType.FreeBusy;
// Return a set of of suggested meeting times.
GetUserAvailabilityResults results = _ews.GetUserAvailability(attendees,
new TimeWindow(StartTime, EndTime),
AvailabilityData.FreeBusyAndSuggestions,
meetingOptions);
weeks = new List<Week>();
List<DateTime> mtTimesColl = new List<DateTime>();
if (results != null)
{
foreach (Suggestion suggestion in results.Suggestions)
{
int cnt = suggestion.TimeSuggestions.Count;
foreach (TimeSuggestion tmesugg in suggestion.TimeSuggestions)
{
if (tmesugg.MeetingTime != null)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "ConsiderTimeZone Value " + ConfigurationManager.AppSettings["ConsiderTimeZone"].ToString().Trim().ToLower());
if (ConfigurationManager.AppSettings["ConsiderTimeZone"].ToString().Trim().ToLower().CompareTo("true")==0)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Within if statement : ConsiderTimeZone");
//List<ArrayList> attendeeColl = new List<ArrayList>();
List<List<DateTime>> attendeeColl = new List<List<DateTime>>();
if (results.AttendeesAvailability[0] != null)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Organizer object found");
if (results.AttendeesAvailability[0].WorkingHours != null)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "WorkingHours " + results.AttendeesAvailability[0].WorkingHours.ToString());
if (results.AttendeesAvailability[0].WorkingHours.TimeZone != null)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Time Zone " + results.AttendeesAvailability[0].WorkingHours.TimeZone.ToString());
if (results.AttendeesAvailability[0].WorkingHours.TimeZone.BaseUtcOffset != null)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "base utc" + results.AttendeesAvailability[0].WorkingHours.TimeZone.BaseUtcOffset.ToString());
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "within base utc off set not null");
var organizerTimeZone = results.AttendeesAvailability[0].WorkingHours.TimeZone.BaseUtcOffset;
KGSGLogger.LogError("Organizer time zone: ", organizerTimeZone.ToString());//till here
foreach (AttendeeAvailability aa in results.AttendeesAvailability)
{
//ArrayList singleAttendeeSlots = new ArrayList();
List<DateTime> singleAttendeeSlots = new List<DateTime>();
//var singleAttendeeSlots = new ArrayList();
KGSGLogger.LogError("Atteendee timezone base offset", (aa.WorkingHours.TimeZone.BaseUtcOffset.ToString()));
KGSGLogger.LogError("Converted start time to organizer timezone ", (Convert.ToDateTime(aa.WorkingHours.StartTime.ToString()).Add(organizerTimeZone - aa.WorkingHours.TimeZone.BaseUtcOffset)).ToString());
KGSGLogger.LogError("Converted end time to organizer timezone ", (Convert.ToDateTime(aa.WorkingHours.EndTime.ToString()).Add(organizerTimeZone - aa.WorkingHours.TimeZone.BaseUtcOffset)).ToString());
if ((Convert.ToDateTime(results.AttendeesAvailability[0].WorkingHours.StartTime.ToString())
<= (Convert.ToDateTime(aa.WorkingHours.StartTime.ToString()).Add(organizerTimeZone - aa.WorkingHours.TimeZone.BaseUtcOffset)))
&& (Convert.ToDateTime(results.AttendeesAvailability[0].WorkingHours.EndTime.ToString()))
>= (Convert.ToDateTime(aa.WorkingHours.EndTime.ToString()).Add(organizerTimeZone - aa.WorkingHours.TimeZone.BaseUtcOffset)))
{
DateTime dtConv = tmesugg.MeetingTime;
//mtTimesColl.Add(dtConv);
singleAttendeeSlots.Add(dtConv);
KGSGLogger.LogError("TimeZone consideration taken ", dtConv.ToString());
}
attendeeColl.Add(singleAttendeeSlots);
}
var TimeSLots = attendeeColl.Cast<IEnumerable<DateTime>>().Aggregate((x, y) => x.Intersect(y));
foreach (DateTime meetingTime in TimeSLots)
{
mtTimesColl.Add(meetingTime);
KGSGLogger.LogError("meeting slots ", meetingTime.ToString());
}
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "base utc is null");
}
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Time ZOne is null");
}
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "WorkingHours is null");
}
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "organizer is null");
}
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGMeetingScheduler.ToString(),
"Within else statement : ConsiderTimeZone");
if (results.AttendeesAvailability[0].WorkingHours != null)
{
DateTime dtConv = tmesugg.MeetingTime;
mtTimesColl.Add(dtConv);
KGSGLogger.LogError("NO TIMEZONE CONVERSION Available slot: ", dtConv.ToString());
}
}
}
}
}
mtTimesColl.Sort((x, y) => x.CompareTo(y));
weeks.Add(GetAvailableSlots(StartTime, EndTime, intNumberOfWeeks, mtTimesColl));
}
else
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "Refine Params: GetUserAvailabilityResults is null");
throw new Exception("Refine Params: GetUserAvailabilityResults is null");
}
}
});
}
catch (Exception ex)
{
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), string.Format("Error in RefineParams(); " + "{0}/n{1}/n{2}", ex.Message, ex.StackTrace ?? string.Empty, ex.InnerException == null ? string.Empty : ex.InnerException.Message));
}
KGSGLogger.LogError(SPCustomCategory.kGSGService.ToString(), "RefineParams ends");
return weeks;
}