How to retrieve multiple Extended Properties use EWS and Java - c#

I have created two "User-Defined" fields in the contacts folder in Outlook 2010. I'm using the Java port of the C# EWS API. My goal is to read the value of the fields for each contact for a specific user. The problem to this point has been retrieving more than one field. In my code below you'll find that I define multiple (2) fields that are extended properties that I want to access. However, in the output, I only retrieve, at most, 1 field. For Example, a contact has both fields, it will only return the first one it finds. If it only has 1 of the two fields, it will return which ever one is populated. Any ideas?
private static void printContacts(ExchangeService service, int numOfContacts) throws Exception{
// Defined the properties you want to retreive
ExtendedPropertyDefinition propertyOne = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "property1", MapiPropertyType.String);
ExtendedPropertyDefinition propertyTwo= new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "property2", MapiPropertyType.String);
// Push the customer properties into an arary
ExtendedPropertyDefinition[] list = {propertyOne , propertyTwo};
// Create a property set to hold the properties
PropertySet propertySet = new PropertySet(BasePropertySet.FirstClassProperties, list);
// Get items from mail box
ItemView view = new ItemView(numOfContacts);
try {
FindItemsResults<Item> contactResults = service.findItems(WellKnownFolderName.Contacts, view);
for(Item item : contactResults.getItems()){
item.load();
Contact contact = Contact.bind(service, item.getId(), propertySet);
System.out.println("count: " + contact.getExtendedProperties().getCount());
for(ExtendedProperty prop : contact.getExtendedProperties()){
String propertyName = prop.getPropertyDefinition().getName().toString();
String propertyValue = prop.getValue().toString();
System.out.println(propertyName +" : "+ propertyValue);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
When I print out the count of extended properties, its always one, even if both extended properties are set. Any help would be appreciated.

Related

Extended property not adhering to EmailMessage

I am running code that looks to add an extended property along with a value. Seems to run fine. When I iterate over the MailItems, I do not see any evidence of the extended property.
Code to extend:
EmailMessage email2 = EmailMessage.Bind(service, result.Items[0].Id);
Guid MyPropertySetId = new Guid("{C11FF724-AA03-4555-9952-
8FA248A11C3E}");
ExtendedPropertyDefinition extendedPropertyDefinition = new
ExtendedPropertyDefinition(MyPropertySetId, "ServiceCat",
MapiPropertyType.String);
email2.SetExtendedProperty(extendedPropertyDefinition, "Level2 big daddy");
email2.Update(ConflictResolutionMode.AlwaysOverwrite);
Code to read extended property:
foreach (Item item in result.Items)
{
Console.WriteLine(item.Subject);
if (item.ExtendedProperties.Count > 0)
{
// Display the name and value of the extended property.
foreach (ExtendedProperty extendedProperty in item.ExtendedProperties)
{
Console.WriteLine(" Extended Property Name: " + extendedProperty.PropertyDefinition.Name);
Console.WriteLine(" Extended Property Value: " + extendedProperty.Value);
}
}
}
I have tried to reconnect to iterate over emails to see if extended property is there but array length remains 0. I.e. the foreach never kicks in.
I am assuming extended preoprty is saved at the exchange "email2.Update(ConflictResolutionMode.AlwaysOverwrite)" and should be able to be read back
Any advice appreciated.
You need to load the extended property using a Property set before you will be able to enumerate it on a Message eg
PropertySet psPropSet = new PropertySet();
psPropSet.Add(extendedPropertyDefinition );
ItemView itemView = new ItemView(1000);
itemView.PropertySet = psPropSet;
You can then just use TryGetProperty to Get the extendedproperty if set

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);

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...
}

Unable to fetch built in properties of email along with the extended property

I am working with Exchange Web Services Managed API. I am adding a single extended property to mail items in inbox as they get processed based on some condition. Thus, not all mails will get this extended property attached to them.
Next I am refetching all mails in inbox and if they have this property attached to them, I process them again.
Below is the simple method getAllMailsInInbox(), I have written to refetch the mails in inbox:
class MyClass
{
private static Guid isProcessedPropertySetId;
private static ExtendedPropertyDefinition isProcessedPropertyDefinition = null;
static MyClass()
{
isProcessedPropertySetId = new Guid("{20F3C09F-7CAD-44c6-BDBF-8FCB324244}");
isProcessedPropertyDefinition = new ExtendedPropertyDefinition(isProcessedPropertySetId, "IsItemProcessed", MapiPropertyType.String);
}
public List<EmailMessage> getAllMailsInInbox()
{
List<EmailMessage> emails = new List<EmailMessage>();
ItemView itemView = new ItemView(100, 0);
FindItemsResults<Item> itemResults = null;
PropertySet psPropSet = new PropertySet(BasePropertySet.IdOnly);
itemView.PropertySet = psPropSet;
PropertySet itItemPropSet = new PropertySet(BasePropertySet.IdOnly,
ItemSchema.Attachments,
ItemSchema.Subject,
ItemSchema.Importance,
ItemSchema.DateTimeReceived,
ItemSchema.DateTimeSent,
ItemSchema.ItemClass,
ItemSchema.Size,
ItemSchema.Sensitivity,
EmailMessageSchema.From,
EmailMessageSchema.CcRecipients,
EmailMessageSchema.ToRecipients,
EmailMessageSchema.InternetMessageId,
ItemSchema.MimeContent,
isProcessedPropertyDefinition); //***
itemResults = service.FindItems(WellKnownFolderName.Inbox, itemView);
service.LoadPropertiesForItems(itemResults.Items, itItemPropSet);
String subject = itItem.Subject; //Exception: "You must load or assign this property before you can read its value."
//....
}
}
As you can see, on call service.LoadPropertiesForItems(), it does not load any properties, thus resulting in You must load or assign this property before you can read its value. exception while accessing any of those properties.
If I remove isProcessedPropertyDefinition from the itItemPropSet property set, it fetches all the properties properly.
So can I just know how can I fetch all built in EmailMessage properties along with the extended property?
Your GUID is two digits too short after the last dash. Strange that you're not seeing a FormatException. Still, you should update your code to inspect the GetItemResponse for each item. That way if some error occurs on one item, your code can be aware of it. That means you'll need to make another collection to return.
Update your code with this:
ServiceResponseCollection<ServiceResponse> responses = service.LoadPropertiesForItems(itemResults.Items, itItemPropSet);
foreach (ServiceResponse response in responses)
{
if (response.Result == ServiceResult.Error)
{
// Handle the error associated
}
else
{
String subject = (response as GetItemResponse).Item.Subject;
}
}
Instead of doing
service.LoadPropertiesForItems(itemResults.Items, itItemPropSet);
Try doing
itemResult.LoadPropertiesForItems(itItemPropSet);
Casue once you have the item, you can load the extended property of the item by loading the specific one.

How can I get / set an extended property from a contact using Microsoft's EWS API?

I think I'm creating it properly, like as follows. c is a Contact, and I'm just trying to store a unique identifier considering that ItemId which is provided by EWS isnt static...
propertySetId = System.Guid.NewGuid();
// Create a definition for the extended property.
ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, "itemGUID", MapiPropertyType.String);
c.SetExtendedProperty(extendedPropertyDefinition, propertySetId.ToString());
c.Update(ConflictResolutionMode.AlwaysOverwrite);
When I try to pull this back out when searching for the contact based on something else, like first name, I'm getting a null returned. I'm trying to get the value by:
foreach (Item c in findResults.Items)
{
foreach(ExtendedProperty extendedProperty in c.ExtendedProperties)
{
if(extendedProperty.PropertyDefinition.Name == "itemGUID")
{
results[i] = extendedProperty.Value.ToString();
}
}
}
EDIT: code for findResults
List<SearchFilter> searchFilters = new List<SearchFilter>();
searchFilters.Add(new SearchFilter.IsEqualTo(itemGUID, value));
//can be more filters here depending on situation
SearchFilter filter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchFilters.ToArray());
findResults = service.FindItems(WellKnownFolderName.Contacts, filter, view);
You need to assign the PropertySet in the ItemView to tell EWS what properties to include when you search using FindItems. If you don't include it in your ItemView it won't be available for reading.The alternative approach is to use the Contact.Bind and request the property for each Contact in question (more service requests, but sometimes necessary).
See Viewing Extended Properties using EWS for a full example on working with Extended Properties in EWS.
Approach #1: Retrieve Extended Property for all Contacts
ExtendedPropertyDefinition propDef = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, "itemGUID", MapiPropertyType.String);
ItemView view = new ItemView(50) { PropertySet = new PropertySet(propDef) };
Approach #2: Bind one contact at a time if you have a Contact ID
ExtendedPropertyDefinition propDef = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, "itemGUID", MapiPropertyType.String);
Contact contact = Contact.Bind(service, contactID, new PropertySet(propDef));

Categories