Currently I'm working on migration of one big project from MAPI CDO to EWS (Managed API 2.2) to support Ex2016. All things were migrated well except one: I can't find the way how to read\write Attachments Extended Properties. Does anybody know how to do that or may be some workaround? This is very critical for me and I would be very appreciate for any help.
---Update:
Also tried to use native EWS to get property of attachment but without success too:
var ret = esb.GetAttachment(new GetAttachmentType()
{
AttachmentIds = new []{new AttachmentIdType()
{
Id = "AAMkADVhNjUzMzMyLTRiMDYtNDc4OS1hYjJjLWI1ZDA4ZWFhYTJkZQBGAAAAAADqFaOFYZSeQI5UObwGbjIJBwAOgaos6ORVS5+o5bQovn/kAAAAeN2cAAAOgaos6ORVS5+o5bQovn/kAAAeCoIuAAABEgAQAJPAuRg2gipPmEKfgW26mFU=",
}},
AttachmentShape = new AttachmentResponseShapeType()
{
BodyType = BodyTypeResponseType.Best,
BodyTypeSpecified = true,
IncludeMimeContent = false,
IncludeMimeContentSpecified = true,
AdditionalProperties = new []
{
new PathToExtendedFieldType() { PropertyType = MapiPropertyTypeType.Integer, PropertyTag = "0x3705"},
new PathToExtendedFieldType() { PropertyType = MapiPropertyTypeType.Integer, PropertyTag = "0x0E21"},
}
}
});
The response doesn't contain any of requested properties.
--- Update 2:
In project we use next properties of attachments:
PR_RECORD_KEY, PR_DISPLAY_NAME, PR_RENDERING_POSITION
PR_ATTACH_ENCODING, PR_ATTACH_NUM, PR_ATTACH_METHOD, PR_ATTACH_LONG_FILENAME, PR_ATTACHMENT_HIDDEN, PR_ATTACH_CONTENT_ID, PR_ATTACH_FLAGS, PR_ATTACH_MIME_TAG, PR_ATTACH_CONTENT_LOCATION, PR_ATTACH_SIZE
Also we create a couple of Custom Extended Properties with custom Property Set and tag some attachments with that props.
Some of Properties can be found in object model of EWS/ManagedApi like PR_ATTACH_SIZE but the problem with others and with custom props.
So we need to read/write standard attachment properties as well as custom.
In project we mark attachment itself, not embedded Item.
You can't access extended properties on Attachments or the Recipients collection in EWS outside of those properties that are made accessible as strongly typed properties by the API. The only place you can use Extended properties are at the message level.
That said can you explain more as to how your using Extended properties eg are these extended properties on embeded items. If that is the case then you could access those extended properties via the Item Attachment.
Looking at your code 0x3705 is the PR_ATTACH_METHOD property on an attachment there is no equivalent to this in EWS, rather EWS will return a different Attachment Class based on the Attachment type. Eg ItemAttachment, FileAttachment or ReferanceAttachment (eg for OneDrive Attachments). 0x0E21 is that Attachment number EWS is going to return the Attachments in the order of that number in GetItem request so you can compute that yourself. But the property is useless in EWS because to get an Attachment you need the EWSId unlike MAPI.
Cheers
Glen
Related
i always have the following errors in my inbox:
Native View To inspect the native object, enable native code debugging.
I have the following code:
public void CheckForEmails()
{
Outlook._Application _app = new Outlook.Application();
Outlook._NameSpace _ns = _app.GetNamespace("MAPI");
Outlook.MAPIFolder inbox = _ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
_ns.SendAndReceive(true);
List<Outlook.MailItem> ReceivedEmail = new List<Outlook.MailItem>();
Outlook.Items items = inbox.Items;
foreach (Outlook.MailItem mail in inbox.Items)
ReceivedEmail.Add(mail);
}
I have two mail addresses set up in Outlook.
IMAP and Exchange.
Perhaps relevant to mention.
First of all, don't use the foreach loop with COM objects. You will not be able to release COM objects in a timely manner and can reach the limit of COM references hold with the Exchange server.
The Items class from the Outlook object model is a collection of items that can represent your managed list of emails.
Where can I found MessageId of a mail in Outlook?
I need Id to pass it to Graph API, so this is not correct id.
It must be something like that:
AAE3NzVkZTAwLTNiM2MtNGUwNS1iYzNiLTZjNjM0YTc5985zJhZABGAAAAAABKvyNK5HPTSZZiT7al48txBwC12ftoWcMmSKHMBQzQpO
rDAAAAAAEMAAC12ftoWcMmSKHMBQzQKKJAADRLyVbAAA=
I need this for Graph -> Message API.
Outlook uses the EntryID property value for identifying items in the store. To get EwsId you must convert it using the following code:
string ConvertHexEntryIdToEwsId(ExchangeService esb, string sID, string strSMTPAdd)
{
AlternateId objAltID = new AlternateId();
objAltID.Format = IdFormat.HexEntryId;
objAltID.Mailbox = strSMTPAdd;
objAltID.UniqueId = sID;
AlternateIdBase objAltIDBase = esb.ConvertId(objAltID, IdFormat.EwsId);
AlternateId objAltIDResp = (AlternateId)objAltIDBase;
return objAltIDResp.UniqueId;
}
But I'd suggest using the approach described on the Convert Outlook REST API item id to MAPI EntryID page:
if you wanted to fetch a page of your messages and include the PR_ENTRYID, you could make a GET request to:
https://graph.microsoft.com/v1.0/me/messages?$expand=singleValueExtendedProperties($filter=id%20eq%20'Binary%200x0FFF')
Is it possible to share extended properties with invited attendees of an Exchange appointment? In other words, is it possible to create a meeting in Exchange using EWS which would pass it's extended properties (custom fields) to attendee's copies of the meeting (assuming they use Exchange as well)?
So far non of the options I tried worked - I can only see the properties in the organizer's meeting through both EWS and Outlook.
A peace of working example or explanation of solution would be great.
UPDATE. Based on this thread here's what I tried (and it didn't work):
var exchangeAppointment = new Appointment(exchange);
...
ExtendedPropertyDefinition extendedPropertyDefinition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "keyword", MapiPropertyType.String);
exchangeAppointment.SetExtendedProperty(extendedPropertyDefinition, "value");
var sendModeForSave = SendInvitationsMode.SendToAllAndSaveCopy;
await exchangeAppointment.Save(sendModeForSave);
foreach (var email in command.MeetingAttendeeEmails) {
exchangeAppointment.RequiredAttendees.Add(email);
}
var sendModeForUpdate = SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy;
await exchangeAppointment.Update(ConflictResolutionMode.AlwaysOverwrite, sendModeForUpdate);
You could create appointment with custom properties in EWS, then view custom extended properties by using the EWS Managed API 2.0
You could refer to this code:
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();
For more information, you could refer to these link:
Create appointment with custom properties in EWS
Viewing custom extended properties by using the EWS Managed API 2.0
Set CustomProperties on appointment for all attendees
I am using Ms Dynamic Web Api with Simple OData. I need to add new record for link entities.
I am using the below code snip and refer the documentation on
https://github.com/object/Simple.OData.Client/wiki/Adding-entries-with-links
var newContactData = await _oDataClient
.For<Contacts>()
.Set(new
{
firstname = contactData.ContatDetails.firstname,
lastname = contactData.ContatDetails.lastname,
emailaddress1 = contactData.ContatDetails.emailaddress1
})
.InsertEntryAsync(true);
var newContactLink = await _oDataClient.For<New_project_contactses>()
.Set(new
{
_new_contact_project_name_new_value = contactData.ContatDetailsLink._new_contact_project_name_new_value,
new_project_contactsid = new Guid("0eb46b24-21a2-e611-80eb-c4346bc5b2d4"),
new_contact_type = contactData.ContatDetailsLink.new_contact_type,
})
.InsertEntryAsync(resultRequired: true);
i am getting exception
CRM do not support direct update of Entity Reference properties, Use
Navigation properties insteadS
Well, it is possible, but you need to use the special "#odata.bind" syntax to update your single-navigation properties.
For example, to update an account so that it references an existing primarycontactid, you can use a PATCH operation to the /api/data/v8.2/accounts endpoint with the following body:
{
"name":"Sample Account",
"primarycontactid#odata.bind":"/contacts(00000000-0000-0000-0000-000000000001)"
}
See https://msdn.microsoft.com/en-us/library/gg328090.aspx#Anchor_3 (it is discussed in terms of creating an entity, but it works for updating as well).
I figure out the issue With Dynamc CRM you cannot directly update reference entities Field. You can identify reference entity properties start with "_".
My company requires me to use Outlook for my E-mail. Outlook does virtually nothing the way I want to do it and it frustrates me greatly. (I'm not trying to start a flame war here, it must do exactly what thousands of CEO's want it to do, but I'm not a CEO.)
I would like to be able to automatically extract the thousands of E-mails and attachments currently in my Outlook account and save them in my own alternative storage format where I can easily search them and organize them the way I want. (I'm not requesting suggestions for the new format.)
Maybe some nice open source program already can do this... that would be great. Please let me know.
Otherwise, how can I obtain the message content and the attachments without going through the huge collection manually? Even if I could only get the message content and the names of the attachments, that would be sufficient. Is there documentation of the Outlook mail storage format? Is there a way to query Outlook for the data?
Maybe there is an alternative approach I haven't considered?
My preferred language to do this is C#, but I can use others if needed.
Outlook Redemption is the best thing currently to use that I have found. It will allow you to get into the messages and extract the attachments and the message bodies. i am using it now to do just that.
Here is some code I use in a class. I included the constructor and the processing function I use to save off the attachments. I cut out the code that is specific to my needs but you can get an idea of what to use here.
private RDOSession _MailSession = new RDOSession();
private RDOFolder _IncommingInbox;
private RDOFolder _ArchiveFolder;
private string _SaveAttachmentPath;
public MailBox(string Logon_Profile, string IncommingMailPath,
string ArchiveMailPath, string SaveAttPath)
{
_MailSession.Logon(Logon_Profile, null, null, true, null, null);
_IncommingInbox = _MailSession.GetFolderFromPath(IncommingMailPath);
_ArchiveFolder = _MailSession.GetFolderFromPath(ArchiveMailPath);
_SaveAttachmentPath = SaveAttPath;
}
public void ProcessMail()
{
foreach (RDOMail msg in _IncommingInbox.Items)
{
foreach (RDOAttachment attachment in msg.Attachments)
{
attachment.SaveAsFile(_SaveAttachmentPath + attachment.FileName);
}
}
if (msg.Body != null)
{
ProcessBody(msg.Body);
}
}
}
edit:
This is how I call it and what is passed
MailBox pwaMail = new MailBox("Self Email User", #"\\Mailbox - Someone\Inbox",
#"\\EMail - Incomming\Backup", #"\\SomePath");
If you want to extract your e-mails take a look at
Outlook Email Extractor
at codeproject
http://69.10.233.10/KB/dotnet/OutlookEmailExtractor.aspx
rob
www.filefriendly.com