EWS: Exchange Items not available right after Update - c#

I'm working on a project to sync calendar items from specific Exchange users to another application and back. In the other application there are meetings, too. My problem in several parts of my project is that I want to add attendees to the appointment, then get the appointment with the credentials of the attendee and accept it. But when I want to check bind the new appointment immediatly after updating the appointment there is no Item with the iCalUid in the folder. When I wait 2000ms after updating the meeting request is there but I don't think this is best practice. I have a short code sample:
string attendeeAddress = "mymailaddress";
ExchangeService service =
new ExchangeService(ExchangeVersion.Exchange2013)
{
Url = new Uri("https://exchange.sample.de/EWS/Exchange.asmx"),
Credentials = new WebCredentials("username", "password", "domain")
};
Appointment app = Appointment.Bind(service, id);
app.RequiredAttendees.Add(attendeeAddress);
app.IsResponseRequested = false;
app.Update(ConflictResolutionMode.AutoResolve);
CalendarView view = new CalendarView(app.Start, app.End);
Thread.Sleep(2000);
FindItemsResults<Appointment> attendeeApps =
serviceAttendee.FindAppointments(WellKnownFolderName.Calendar, view);
Appointment appAttendee;
foreach (Appointment a in attendeeApps)
{
if (a.ICalUid.Equals(app.ICalUid))
{
appAttendee = Appointment.Bind(serviceAttendee, a.Id);
}
}
appAttendee.Accept(false);

From the looks of what your doing your adding an attendee to a meeting and then connecting to the attendees Mailbox to accept that meeting ? If that's the case on the backend this is going to produce a Meeting Invitation that will need to be sent via Email and routed to the Attendees Mailbox via the Hub Transport Role. Even if all the recipients and server roles are on the same server you will need to allow time for the message to be delivered to the Attendees Mailbox this is just the normal way Exchange handles Meeting for local (or remote attendees) it will never be instant as Exchange stores each copy of the Appointment as a separate store Item.

Related

How to stop meeting being stripped on forward (EWS)

I am using C# with the Exchange Web Service (EWS).
I have meetings that I need to forward and whenever I do they get stripped, but only from some accounts and not others. The link for the meeting is still there but it is not being recognised by the online Outlook as a meeting item, nor by Teams which is connected to the account.
This even happens if I manually forward, but again only if I forward emails that are from some accounts - some other accounts are fine!
I'm using this on incoming emails:
var fwdEmailArr = new EmailAddress[1];
fwdEmailArr [0] = fwdEmail;
MeetingRequest appointment = MeetingRequest.Bind(service, email.Id);
appointment.Forward("", fwdEmailArr);
This is the same issue if I use the email.forward as well, etc.
However, if I create a new appointment and send it, it doesn't get stripped - this is with the same addresses.
Appointment appt = new Appointment(service);
appt.Subject = email.Subject;
appt.Body = appointment.Body;
appt.Start = appointment.Start;
appt.End = appointment.End;
appt.Location = appointment.Location;
appt.RequiredAttendees.Add(fwdEmail);
foreach (var reqAtt in appt.RequiredAttendees)
{
appt.RequiredAttendees.Add(reqAtt);
}
foreach (var reqAtt in appt.OptionalAttendees)
{
appt.OptionalAttendees.Add(reqAtt);
}
appt.RequiredAttendees.Add(appointment.From.Address);
appt.Save(SendInvitationsMode.SendToAllAndSaveCopy);
So, I could do this but it means that they are no longer the same meeting and declining the original wont decline this. Unless there's a way I can connect the meetings or something?
Any ideas how I can stop the meeting being stripped?
Or alternatively just add another recipient to the current meeting, that will show on their calendar?
If anyone comes here with a similar issue, it turns out that, first of all you need to make sure you define the correct server version on the service declaration:
service = new ExchangeService(ExchangeVersion.Exchange2016){}
In addition, for some reason some images when attached to the forwarded email for some reason confuse EWS and make it think there's no meeting. I got around this by scanning the MIME content and just extracting the calendar block and deleting all other attachments.
This has been working flawlessly for about 5 months.

How to receive the notification from Exchange when a participant was add or delete in an existing appointment

I use the EWS managed API "SubscribeToPushNotifications" to get the notification from Exchange when an appointment is created or modified.
It works successfully that I can receive the notifications from Exchange when an appointment is created or modified.
But when I just add or delete a participant in an existing appointment and save(send) this appointment. I can not receive the nofitication from Exchange.
My Question is how to receive the notification from Exchane when I just add or delete a participant in an existing appointment.
By the way, the paramenter of EWS manage API "SubscribeToPushNotifications" I used
new FolderId(WellKnownFolderName.Calendar, new Mailbox(<meetingroom mail address>))
new EventType[] { EventType.Moved, EventType.Created, EventType.Modified }
Add/removing attendees will modify the appointment so should generate a EventType.Modified event in the Organizers calendar. If your looking at events in Attendees or Meeting Rooms (which from you code you appear to be doing) then these calendars will only update based on the recipient and processing of a Meeting Update. Appointments in Exchange are separate store items so the appointment Item in the Organizers Calendar can be change independently on the attendees. The only time the attendees/resource calendar appointment will update is when an update is specifically sent which only happens under certain circumstances. Eg if you just adding an attendee you don't need to notify other attendees (because you not changing the time etc) so an update may or may not be sent (depends on entirely on the client making the update).

Exchange API does not return shared calendar which are shared on other domain

I am using EWS Managed exchange api in c#.
When I fetch all calendar using below code, it's not returning me all calendar.
It's only return my calendarm but there is more calendar which are shared by other.
SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(
FolderSchema.FolderClass, "IPF.Appointment");
FindFoldersResults ffoldres = service.FindFolders(
new FolderId(WellKnownFolderName.Root, "emailId"),
sfSearchFilter, fvFolderView);
We have calendar call as below.
service.FindFolders(new FolderId(WellKnownFolderName.Root, "email")
In this call we pass my email id. (My credential email).
If i need to access other user calendar(Shared calendar). I need to pass other user email address here. like service.FindFolders(new FolderId(WellKnownFolderName.Root, "Other user email").
Service object is created by my credential and just pass email of other user. Now you can get all calendar.

ExchangeService: connecting without credentials, how to retrieve user information?

I am analyzing a users Exchange mailbox with calls to the ExchangeService. This tool needs to run on the client environment periodically and by ommiting the credentials to the service I am connecting to the Exchange Service as the logged in Windows User. I can succesfully loop thrue the folders and items.
Now I want tot retrieve the information about the mailbox being used. Username and (main) E-mail should suffice. But I cannot find anything about how to retrieve this information. Every example provides credentails for the user, or auto-discovering the Exchange service from the e-mail adres. I do not want the user to configure anything :-).
Any suggestions?
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Url = new Uri("https://FQDN/EWS/Exchange.asmx");
???
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.SentItems, new ItemView(100)); // this works
I've tried using service.ResolveName, but that can give multiple answers, even using Environment.UserName
The easiest method to do this is to use ConvertId operation and use unresolvable address (blah#blah.com always works for me) in the Mailbox element. Exchange should convert this to the actual Mailbox in the response. eg
Folder chk = Folder.Bind(service, WellKnownFolderName.Inbox);
AlternateId aiItem = new AlternateId();
aiItem.Mailbox = "Blah#Blah.com";
aiItem.UniqueId = chk.Id.UniqueId;
aiItem.Format = IdFormat.EwsId;
String CasServer = service.Url.Host.ToString();
AlternateIdBase caid = service.ConvertId(aiItem, IdFormat.HexEntryId);
Console.WriteLine(((AlternateId)caid).Mailbox);
Cheers
Glen

How to save an outlook appointment in users calendar?

I am developing an asp.net web application which allows users to syn any Event from the gridView to there Outlook appointment using the following code:
private void generateOutlookAppointment(string subject, string location, string startDate, string endDate)
{
string body = "Test Data for Body.";
Outlook.Application outlookApp = new Outlook.Application();
Outlook.AppointmentItem oAppointment = (Outlook.AppointmentItem)outlookApp.CreateItem(Outlook.OlItemType.olAppointmentItem);
oAppointment.Subject = subject;
oAppointment.Body = body ;
oAppointment.Location = location;
oAppointment.Start = DateTime.Parse(startDate).AddHours(9);
oAppointment.End = DateTime.Parse(endDate).AddHours(9);
oAppointment.ReminderSet = true;
oAppointment.ReminderMinutesBeforeStart = 15;
oAppointment.Importance = Outlook.OlImportance.olImportanceHigh;
oAppointment.BusyStatus = Outlook.OlBusyStatus.olBusy;
oAppointment.Save();
}
Code works fine when I run locally in visual studio localhost, but fails on server.
Not sure logically would it be able to store an outlook appointment on client outlook since the code is running at server.
Please point me to right direction, even in case I need to use different approach.
Thanks in advance.
Outlook, just like any other Office app, cannot be used in a service (such as IIS).
See How to access client's outlook in ASP.net? for alternatives.
I always did it as an email to the user. A lot of sites online have the required data that needs to be sent to convert an email to a meeting request, here's an example.
http://sahannet.blogspot.com/2010/09/create-outlook-vcalendar-reminder-file.html

Categories

Resources