Exchange EWS Managed API Error while Updating EmailMessage on certain properties - c#

I am working against the Exchange 2010 EWS Managed API and trying to update emails (EmailMessage).
While updating the EmailMessage's Sender.Name property, I get an exception upon Update(), but if I try to update the EmailMessage's Subject, it works just fine.
private void UpdateEmail(ItemId itemId)
{
try
{
EmailMessage emailMessage = EmailMessage.Bind(service, itemId, new PropertySet(EmailMessageSchema.Sender, EmailMessageSchema.Subject));
// Test 1 - this works:
emailMessage.Subject = "Testing";
emailMessage.Update(ConflictResolutionMode.AlwaysOverwrite);
// Test 2 - this does NOT work (if I comment out the previous 2 lines btw):
emailMessage.Sender.Name = "John Smith";
emailMessage.Update(ConflictResolutionMode.AlwaysOverwrite); // exception thrown
...
I get the following error from Test 2:
The request failed schema validation: The element 'Updates' in namespace 'http:/
/schemas.microsoft.com/exchange/services/2006/types' has incomplete content. Lis
t of possible elements expected: 'AppendToItemField, SetItemField, DeleteItemFie
ld' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types'.

EWS doesn't support changing the Sender address via the Strongly typed properties like you are trying. The only way they maybe successful is to modify the underlying extended properties and generating oneoff or wrapped entry-id where applicable the props you need to update are
PR_SENDER_ADDRTYPE_W
PR_SENDER_EMAIL_ADDRESS_W
PR_SENDER_NAME_W
PR_SENDER_ENTRYID
PR_SENDER_SEARCH_KEY
PR_SENT_REPRESENTING_EMAIL_ADDRESS_W
PR_SENT_REPRESENTING_ADDRTYPE_W
PR_SENT_REPRESENTING_NAME_W
PR_SENT_REPRESENTING_ENTRYID
PR_SENT_REPRESENTING_SEARCH_KEY
Note there maybe others as well you need to use a MAPI editor like OutlookSpy of MFCMapi to look at an item yourself.
Cheers
Glen

Related

TFS 2018 API: Can access workitems but not workitem API end point

I created a middleware app that will pull work item data from TFS.
I was able to do this using the workitems end point.
http://sampleserver:8080/tfs/sampleproject/_apis/wit/wiql?api-version=4.0/workitems?ids=1,2,3
Now, I also need to get the work item links per work item. Per docu I would need to access the workitem with expand items. But unfortunately, work item end point does not seem to work.
http://sampleserver:8080/tfs/sampleproject/_apis/wit/wiql?api-version=4.0/workitem/3
Am I missing something here?
According to your description, looks like you just want the URL of created WorkItem, so that anyone when click on URL, created Work Item will be Open.
https://tfsurl:8080/tfs/DefaultCollection/PatrickProject/_workitems/edit/172/
The URL should be above format and here DefaultCollection is the collection name and the PatrickProject is the project name. I used this url and got rid of the id '172' in this case and use the ID of newly created work item. This would return the URL to go to the work item HTML page.
So it's a fixed format, if you have Newly Created WorkItem ID and collection name , project name, you just need to follow above format and change the last value of work item ID. That's it , ignore of which work item type you created.
If you want do this with code, do not use Rest API, you need to use client API, sample snippet:
var tfsURI = new Uri("http://test:8080/tfs");
var networkCredential1 = new NetworkCredential("test", "test!");
ICredentials credential = (ICredentials)networkCredential1;
Microsoft.VisualStudio.Services.Common.WindowsCredential winCred = new Microsoft.VisualStudio.Services.Common.WindowsCredential(credential);
VssCredentials vssCredentials = new VssCredentials(winCred);
using (TfsTeamProjectCollection collection = new TfsTeamProjectCollection(tfsURI, vssCredentials))
{
collection.EnsureAuthenticated();
TswaClientHyperlinkService hyperlinkService =
collection.GetService<TswaClientHyperlinkService>();
String TFSurl = hyperlinkService.GetWorkItemEditorUrl(17648).ToString(); //17648 WorkItem ID
}
Hope this Helps!
To get specific work item information you need to use the Get Workitem API call so try http://sampleserver:8080/tfs/sampleproject/_apis/wit/workitems/3?api-version=4.0 instead.
You can also use this http://sampleserver:8080/tfs/sampleproject/_apis/wit/workitems/3?$expand=Links&api-version=4.0 and this will return the work with Id of 3 and all it's links (parent, attached files, changetset, etc.)
Notice that the api-version=4.0 with change depending on the version of TFS/Service you are using and should always be the last string in the REST call.

How to fetch all headers of several messages in MailKit

In MailKit,
You can fetch the IMessageSummary (containing the specified headers and the full message) for several messages with the following
ImapFolder folder;
List<UniqueId> uids;
var messageSummaries = folder.Fetch(uids,
MessageSummaryItems.Full,
new HashSet<string>{"X-Mailer"});
If a pass an empty HashSet<string>, I get a System.ArgumentException: The set of header fields cannot be empty.
How can I fetch all headers available ?
Note: I know that I could get the headers on each message, one by one, but it is too slow to match my performance needs.
Hacking into MailKit
As MailKit is open-source, I just modified the code of ImapFolderFetch to handle the fetch for all headers and made a pull request. The owner of the library improved it by adding a new value in MessageSummaryItems.
Usage:
var messageSummaries = folder.Fetch(uids, MessageSummaryItems.Headers);
Note: Until a new release is done, you ll have to build your own from github master.

MailKit From Address

Im using mailKit in asp mvc core to collect email from a IMAP mailbox.
I return the message using the command
var message = inbox.GetMessage(uid)
This returns all the results of the message. From here i want to access the sender email address (not including the name). After breakpointing on the above line i can see that the variable message has the following property
message
-From
--From(Array)
---From(item)
----Name (name of the sender)
----Address(email of the sender)
When referencing the above above using the message i am able to receive the name, however the address is not listed (within intelisence, nor will it build)
var name = message.From[0].Name.ToString()
Does anyone know why this would be visible as properties of the variable but not accessible via the code?
i simply want to
var name = message.From[0].Name.ToString()
The MimeMessage.From property is a InternetAddressList (more-or-less List<InternetAddress>).
InternetAddress is an abstract base class for MailboxAddress and GroupAddress which only contains a Name property as you've discovered.
In order to get the Address, you first need to cast it to a MailboxAddress... but only if it is actually a MailboxAddress or you'll get a cast exception.
InternetAddressList has a convenience property called Mailboxes which can be used to iterate over a flattened list of the MailboxAddresses contained within.
You can use this code block.
message.From.OfType<MailboxAddress>().Single().Address;
Another solution:
message.From.Mailboxes.Single().Address;

HTML to Note content

When I trying to write some HTML text to Note, I have error (I think because HTML have some prohibited tags):
Evernote.EDAM.Error.EDAMUserException
When I use the same HTML with:
ENNote.Content = ENNoteContentAdvanced.NoteContentWithSanitizedHTML(HTML);
it works fine.
But I need get notes by ID, for updating. And I am not understand how I can write correctly HTML to Note (in HTML I have tables), or catching ENNote by GUID.
UPD.
I writing service for synchronization Notes (EN) between Evernotes and Microsoft Exchange Appointments (MA). When user create/update EN, my service create/update MA. When user update MA (created from Evernote), my service update EN. For linking I use EN GUID (I store it in MA in extended property). So I can find EN with this code:
List<ExtendedProperty> guids = appointment.ExtendedProperties.Where(ap => ap.PropertyDefinition == guidProp).ToList();
if (guids.Count > 0)
{
string guid = (string)guids.First().Value;
Note sNote = store.GetNote(guid, true, false, false, false);
}
But when I trying to set EN content I have error:
Error code "ENML_VALIDATION"
Parameter = "Document is invalid: no grammar found"
I can't store ENNoteRef in MA, because it object, not string. So I need to find ENNote by GUID (not ENNoteRef), or some stuff to set HTML to Note.Content without loosing tables.
It would help if you provide more of your code that surrounds the ENNote.Content call so we have more context.
Given the code you've provided: once you've created the ENNote and its content using the NoteContentWithSanitizedHTML function, you're then adding the note to the Evernote service with something like the following, correct?
ENNoteRef myNoteRef = ENSession.SharedSession.UploadNote(ENNote, null);
When you do this, you get back a NoteRef object, which is a reference to an actual specific note in the Evernote service. The NoteRef object has a Guid property, which is what you're looking for.

sending and retrieving data to API

I have a solution with 2 projects:
Contains the API
the module where i can select data (combobox etc...)
in the second module i select the API as reference that way i should be able to use data from the first module (my API) using Mollie.Api;
The First thing i want to do is fill a combobow with all the issuers, they should be in issuers.data:
Issuers issuers = mollieClient.GetIssuers();
foreach (Issuer issuer in issuers.data)
{
comboBox1.Items.Add(issuer.name);
}
the problem i have is: mollieClient does not exist in current context
i want to fill another combobox with methods but when i try to do it how they say i should do it doesnt work:
Method methods = new Method();
methods = Mollie.Api.Method.all();
however when i do:
Mollie.Api.Method.* the helper gives me then all the possible methods at *, but how can i get them automaticly in my combobox?
The second thing is when the method and issuer is selected i want to send that data back to the API. The API should be able to proces this and send me a message back that the transaction was a succes.
It appears like you're using mollie-api-csharp. You've written mollieClient, but according to the source Mollie.Api.MollieClient should start with a capital letter.
EDIT: Looks like you're following the how-to-use tutorial from the repo.
I think you forgot to create the MollieClient instance before getting the issuers.
MollieClient mollieClient = new MollieClient();
mollieClient.setApiKey("your_api_key_here");

Categories