Create appointment with custom properties in EWS - c#

I try to add a custom property to created appointments like this:
var newEvent = new Appointment(service)
{
Start = start,
End = end,
Subject = subject,
ReminderMinutesBeforeStart = 15
};
var extendendProperty = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Address, "organizer",
MapiPropertyType.String);
newEvent.SetExtendedProperty(extendendProperty, organizer);
but problem is that when I try get this appointment from server, property ExtendedProperty is empty.
In addition I create new appointment and add 'room' as a required attendee, and when I try get this appointment, I don't get it from my calendar but from room calendar.
So, I want to add extend property to my appointment and invite 'room'. Next get all appointments of the room and here I want read this property. It is even possible?
I read this topic: EWS Create Appointment in exchange with extra custom properties and as I understand I'll must have access to ExtendendPropertyDefinition when I want read this property, and must known id of this appointment before. Now I download all appointments from outlook by this code:
var folderId = new FolderId(WellKnownFolderName.Calendar, new Mailbox(userName));
var calendar = CalendarFolder.Bind(service, folderId, new PropertySet());
return calendar.FindAppointments(new CalendarView(start, stop)).ToList();
EDIT
Thanks Glen Scales!
It almost works as I want, but one thing. I can read this additional property if I download my own appointments, but in that code I download appointments from room calendar.
As I suppose when creating new appointment and add room as required attendant, it create his own appointment and this additional property isn't copied.
So is any way to get this additional property from room appointment, when I add this property to my?

You need to first Create a property set, add the extended property you want to load to that property set. Then tell EWS you want that property returned when you execute the FindAppointment method see https://msdn.microsoft.com/en-us/library/office/dd633697(v=exchg.80).aspx eg in your example
PropertySet YourProperyset = new PropertySet(BasePropertySet.FirstClassProperties);
var extendendProperty = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Address, "organizer",MapiPropertyType.String);
YourProperyset.Add(extendendProperty);
var folderId = new FolderId(WellKnownFolderName.Calendar, new Mailbox(userName));
var calendar = CalendarFolder.Bind(service, folderId);
var calendarView = new CalendarView(start, stop);
calendarView.PropertySet = YourProperyset;
return calendar.FindAppointments(calendarView).ToList();

Related

EWS SetExtendedProperty issue

I'm trying to update an existing email with a new property but I can't get it working.. i'm testing it by adding a custom property with a time stamp string in it..
When i fetch the item in after this has run I can't see any extended properties on it at all...
Here's how i'm trying to save it:
message.Load();
Guid MyPropertySetId = new Guid("{117c7745-5df5-4049-97be-8e2d2d92d566}");
ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(MyPropertySetId, "JNB", MapiPropertyType.String);
message.SetExtendedProperty(extendedPropertyDefinition, DateTime.Now.AddDays(2).ToString());
message.Update(ConflictResolutionMode.AlwaysOverwrite);
And then when I pull it back in again i'm doing this:
if (item.ExtendedProperties.Count > 0)
{
// Display the name and value of the extended property.
foreach (ExtendedProperty extendedProperty in item.ExtendedProperties)
{
if (extendedProperty.PropertyDefinition.Name == "ccpUniqueID")
{
messageAlreadyLogged = AccountMessageManager.HasMessageAlreadyBeenSaved(extendedProperty.Value.ToString());
}
}
}
There just isn't any extended properties....
Exchange will only return the Extended properties you tell it to return so in your case you will need to add that property to a Property Set and then use Load to load it back (this won't happen by default) eg
Guid MyPropertySetId = new Guid("{117c7745-5df5-4049-97be-8e2d2d92d566}");
ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(MyPropertySetId, "JNB", MapiPropertyType.String);
PropertySet psPropSet = new PropertySet(BasePropertySet.FirstClassProperties){extendedPropertyDefinition};
message.Load(psPropSet);

Not getting appointment subject using exchange service C#

I have Full Access for Room mailbox ("conf1#xyz.com"). So i can retrieve all meetings scheduled in Room. In retrieve appointments I'm getting Subject as organizer Name instead of appointment subject.
For Example:
While Creating Appointment given data
Meeting Subject: Test1
Meeting Organizer: Suneel#xyz.com
Attendees: x#xyz.com
Location: conf1#xyz.com
While fetching data from Room getting subject as "Suneel" instead of "Test1"
Can anyone help me on this?
CalendarView cView1 = new CalendarView(fromDate, toDate);
FolderId foldertest = new FolderId(WellKnownFolderName.Calendar, new Mailbox("conf1#xyz.com"));
FindItemsResults<Appointment> findResults =
service.FindAppointments(foldertest, cView1);
findResults.Items.ToList().ForEach(d =>
{
Appointment appointment = Appointment.Bind(service, new
ItemId(d.Id.UniqueId));
roomAppointments.Add(appointment);
});
What your seeing is normal depending on the configuration of the Meeting room eg for privacy reasons you don't want the subject of every Meeting visible to all users that have access to the Meeting room. You can change this configuration using Set-CalendarProcessing https://technet.microsoft.com/en-us/library/dd335046(v=exchg.160).aspx and use the -AddOrganizerToSubject switch

Not able to delete meeting using exchange web services having full access for Room

We have a problem deleting Appointments from Exchange using EWS.
I have Full Access for Room, which I'm able to cancel through outlook but not from our application.
Fetching Calendar Items:
Collection appointments = new Collection();
if (service != null)
{
CalendarView calView = new CalendarView(fromDate, toDate);
FindItemsResults<Item> masterResults = service.FindItems(WellKnownFolderName.Calendar, calView);
masterResults.Items.ToList().ForEach(c =>
{
Appointment appointment = c as Appointment;
appointment = Appointment.Bind(service, new ItemId(c.Id.UniqueId));
appointments.Add(appointment);
});
}
We select one appointment from above list and try to cancel that facing exception.
Cancel Appointment Code:
Appointment appointment = Appointment.Bind(service, new ItemId(uniqueId));
var cancelresult = appointment.CancelMeeting("The metting cancelled.");
we get an exception with the message "User must be an organizer for CancelCalendarItem action." This makes me really confused, because when I inspect the deletedAppointment object my email address is set as the organizer.
I have full access for room and able to cancel meeting from Outlook.
Can anyone help on this?
If you want to cancel an appointment then you need to access the Calendar of the organiser, find that appointment and cancel that appointment. You can't use the copy of the appointment in the Room mailbox as its a different object and also it won't contain all the potential attendees that should get the cancellation message.

EWS Create Appointment in exchange with extra custom properties

Im currently looking at a way to save a few extra properties to an exchange appointment using C#. Currently I can save using the following properties:
Appointment calendar = new Appointment(p_service);
calendar.Subject = calendarS5Subject;
calendar.Body = calendarS5Body;
calendar.Start = calendarS5StartDateTime;
calendar.End = calendarS5EndDateTime;
calendar.IsReminderSet = false;
calendar.Location = calendarS5Location;
calendar.Body.BodyType = BodyType.Text;
calendar.Save();
However I want to be able to store my own custom properties like calendar.EventID and calendar.Blah . Is it possible to save these properties against the appointment and then be able to access them later? It would be even better if it could all be stored as a user control form inside the appoint window. I know you can do this with an outlook addin that uses the type AppointmentItem. However I am yet to find a way to do it with exchange with the type of Appointment.
TIA.
I have now been able to save the extra property using:
Guid EventIDSetGUID = new Guid("{C11FF724-AA03-4555-9952-8FA248A11C3E}");
ExtendedPropertyDefinition extendedPropertyEventID = new ExtendedPropertyDefinition(EventIDSetGUID, "EventID", MapiPropertyType.String);
calendar.SetExtendedProperty(extendedPropertyEventID, calendarS5EventID);
However I am now struggling to read back that property later on. This work right after I have saved the extra property but if I restart the application and then try to read the extra property eventIDProp always returns null. My code for reading:
Guid EventIDReadGUID = new Guid("{C11FF724-AA03-4555-9952-8FA248A11C3E}");
ExtendedPropertyDefinition extendedPropertyEventIDRead = new ExtendedPropertyDefinition(EventIDReadGUID, "EventID", MapiPropertyType.String);
object eventIDProp;
if (calendar.TryGetProperty(extendedPropertyEventIDRead, out eventIDProp) && eventIDProp != calendarS5EventID)
{
}
You can do that with MAPI extended properties:
// Define MAPI extended properties
private readonly ExtendedPropertyDefinition _extendedPropEventId =
new ExtendedPropertyDefinition(
new Guid("{00020329-0000-0000-C000-000000000046}"),
"Event Identifier",
MapiPropertyType.String);
private readonly ExtendedPropertyDefinition _extendedPropBlah =
new ExtendedPropertyDefinition(
new Guid("{00020329-0000-0000-C000-000000000046}"),
"Blah",
MapiPropertyType.String);
...
// Set extended properties for appointment
calendar.SetExtendedProperty(_extendedPropEventId, "custom EventID value");
calendar.SetExtendedProperty(_extendedPropBlah, "custom Blah value");
...
// Bind to existing item for reading extended properties
var propertySet = new PropertySet(BasePropertySet.FirstClassProperties, _extendedPropEventId, _extendedPropBlah);
var calendar = Appointment.Bind(p_service, itemId, propertySet);
if (calendar.ExtendedProperties.Any(ep => ep.PropertyDefinition.PropertySetId == _extendedPropEventId.PropertySetId))
{
// Add your code here...
}

RemoveExtendedProperty throws error when used on an occurrence of a recurring appointment

I am developing an application that syncs an exchange calendar to another calendar. I put extended properties on the exchange appointments in order to preserve the mapping between appointments in the two calendars. Everything is working fine until I try to remove an extended property from an occurrence of a recurring appointment. When I try doing this, I get the error:
The delete action is not supported for this property.
Here is a code snippet that demonstrates the error:
public void ExchangeTest()
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1)
{
Credentials = new NetworkCredential("username", "password", "domain")
};
service.AutodiscoverUrl("username#domain.com");
Appointment appt = new Appointment(service)
{
Recurrence = new Recurrence.DailyPattern(DateTime.Now, 2) { NumberOfOccurrences = 3},
Start = DateTime.Now,
End = DateTime.Now.AddHours(2),
Subject = "Test Appointment"
};
NameResolutionCollection resolutionCollection = service.ResolveName("username", ResolveNameSearchLocation.DirectoryOnly, false);
string mailboxAddress = resolutionCollection.First().Mailbox.Address;
FolderId folderId = new FolderId(WellKnownFolderName.Calendar, mailboxAddress);
appt.Save(folderId);
PropertySet properties = new PropertySet(AppointmentSchema.ICalUid);
appt.Load(properties);
CalendarView view = new CalendarView(DateTime.Today, DateTime.Today.AddDays(8)){PropertySet = properties};
IEnumerable<Appointment> occurrences = service.FindAppointments(folderId, view)
.Where(a => a.ICalUid == appt.ICalUid);
ExtendedPropertyDefinition definition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "TestProperty", MapiPropertyType.String);
Appointment firstOccurrence = occurrences.First();
firstOccurrence.SetExtendedProperty(definition, "test");
firstOccurrence.Update(ConflictResolutionMode.AutoResolve);
//The error occurs on the next line.
firstOccurrence.RemoveExtendedProperty(definition);
firstOccurrence.Update(ConflictResolutionMode.AutoResolve);
//clean up
appt.Delete(DeleteMode.HardDelete);
}
It appears that the error is only thrown for an Exchange 2007 server (It works on 2010). Am I doing something wrong, or is this a problem with Exchange? Is there a way to work around this issue? Any help will be appreciated.
I ended up not using the RemoveExtendedProperty function. Instead, I worked around it by just setting the property again, but setting it to an empty space. I then handled the empty space in code. This appears to be a problem with Exchange or the managed API.
Did you try;
appointment.Delete(DeleteMode.SoftDelete,SendCancellationsMode.SendToAllAndSaveCopy);

Categories