EWS Java: Create new email with existing item as attachment - exchange-server

I am using ews-java-api to create a new email message with an existing item as attachment. I was following Glen's answer to this question to write similar code in java. However, I am getting error - "Items of type EmailMessage are not supported as attachment"
Here is my code snippet for reference:
EmailMessage approvalMessage = new EmailMessage(exchangeService);
ItemAttachment itemAttachment = approvalMessage.getAttachments().addItemAttachment(EmailMessage.class);
MimeContent mimeContent = ewsItem.getMimeContent();
Item attachedItem = itemAttachment.getItem();
attachedItem.setMimeContent(mimeContent);
ExtendedPropertyDefinition prFlags = new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer);
attachedItem.setExtendedProperty(prFlags, "1");
itemAttachment.setName(subject);
approvalMessage.setSubject("Reminder Email with original email as attachment");
approvalMessage.getToRecipients().add("my-email-address");
approvalMessage.send();
approvalMessage is the new email message I am creating
ewsItem is an existing Item which I want to add as attachment to approvalMessage
Question: Is this some issue with ews-java-api that it doesn't accept EmailMessage as attachment type?
What I tried: I replaced ItemAttachment itemAttachment = approvalMessage.getAttachments().addItemAttachment(EmailMessage.class); with ItemAttachment itemAttachment = approvalMessage.getAttachments().addItemAttachment(Item.class);
Post this change, I no longer observe above error. However, the code now throws a stackoverflow error at following line - attachedItem.setMimeContent(mimeContent);
Error stack trace-
Oct 09, 2018 9:02:45 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path []
threw exception [Handler dispatch failed; nested exception is
java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError
at microsoft.exchange.webservices.data.core.PropertyBag.changed
(PropertyBag.java:364)
at microsoft.exchange.webservices.data.property.complex.ItemAttachment.
itemChanged(ItemAttachment.java:96)
at microsoft.exchange.webservices.data.property.complex.ItemAttachment.
serviceObjectChanged(ItemAttachment.java:252)
at microsoft.exchange.webservices.data.core.service.ServiceObject.
changed(ServiceObject.java:85)
at microsoft.exchange.webservices.data.core.PropertyBag.changed
(PropertyBag.java:364)
at microsoft.exchange.webservices.data.property.complex.ItemAttachment.
itemChanged(ItemAttachment.java:96)
at microsoft.exchange.webservices.data.property.complex.ItemAttachment.
serviceObjectChanged(ItemAttachment.java:252)
at microsoft.exchange.webservices.data.core.service.ServiceObject.
changed(ServiceObject.java:85)
Question: Why does specifying Item as attachment class results in stackoverflow error? What is the right way to add existing item as attachment?

The StackOverflowError extends the VirtualMachineError class, which indicates that the JVM is broken, or it has run out of resources and cannot operate.
For more information, you could refer to:
java.lang.StackOverflowError – How to solve StackOverflowError
You could add existing item as attachment use below code:
FolderId folderid= new FolderId(WellKnownFolderName.Inbox,"MailboxName");
Folder Inbox = Folder.Bind(service,folderid);
ItemView ivItemView = new ItemView(1) ;
FindItemsResults<Item> fiItems = service.FindItems(Inbox.Id,ivItemView);
if(fiItems.Items.Count == 1){
EmailMessage mail = new EmailMessage(service);
EmailMessage OriginalEmail = (EmailMessage)fiItems.Items[0];
PropertySet psPropset= new PropertySet(BasePropertySet.IdOnly);
psPropset.Add(ItemSchema.MimeContent);
psPropset.Add(ItemSchema.Subject);
OriginalEmail.Load(psPropset);
ItemAttachment Attachment = mail.Attachments.AddItemAttachment<EmailMessage>();
Attachment.Item.MimeContent = OriginalEmail.MimeContent;
ExtendedPropertyDefinition PR_Flags = new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer);
Attachment.Item.SetExtendedProperty(PR_Flags,"1");
Attachment.Name = OriginalEmail.Subject;
mail.Subject = "See the Attached Email";
mail.ToRecipients.Add("glen.scales#domain.com");
mail.SendAndSaveCopy();
You can’t another message directly, you need to use the MimeContent of the Original Message and then create an ItemAttachment based on that.
Reference to:
Create an email using EWS Exchange and attach another email

Related

EWS Managed API 2, setting FlagStatus

I'm attempting to set the Flag on an e-mail using EWS Managed API 2 - however, I keep getting an error that I can't seem to get past.
I'm doing the following:
ExchangeService exchangeService = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exchangeService.Url = new Uri(<ews url comes from Outlook JavaScript API>);
exchangeService.UseDefaultCredentials = false;
exchangeService.Credentials = new OAuthCredentials(<ews token comes from Outlook JavaScript API>);
And then a little later:
Item item = Item.Bind(exchangeService, new ItemId(<mail id comes from Outlook JavaScript API>), new PropertySet(ItemSchema.Flag));
item.Load();
item.Flag = new Flag() { FlagStatus = ItemFlagStatus.Flagged };
item.Update(ConflictResolutionMode.AutoResolve);
What am I missing?
I keep getting this error:
You must load or assign this property before you can read its value.
UPDATE: Ok, it turned out the this error was caused by some other code which has been corrected.
Now I'm getting this error instead:
The requested web method is unavailable to this caller or application.

FaultException when using ExecuteTransactionRequest (CRM 2015)

I'm doing a bit of a technical investigation into the ExecuteTransactionRequest. It's not something I've ever used before so I knocked up a very quick experiment just to see how it works. However, when sending off the request the OrganizationService is throwing back a FaultException (below). What I believe is happening is that my version of CRM doesn't support that OrganizationRequest. Although I'm pretty sure I have the right assemblies and version.
Can anyone please shed some light on what I'm missing?
CRM Deployment Version: 7.0.1.129
Organization Version: 7.0.2.53
Microsoft.Xrm Assembly Version: 7.0.0.0 (Also happened with 8.0.0.0)
An unhandled exception of type 'System.ServiceModel.FaultException'
occurred in Microsoft.Xrm.Sdk.dll
Additional information: The formatter threw an exception while trying
to deserialize the message: There was an error while trying to
deserialize parameter
http://schemas.microsoft.com/xrm/2011/Contracts/Services:request. The
InnerException message was 'Error in line 1 position 451. Element
'http://schemas.microsoft.com/xrm/2011/Contracts/Services:request'
contains data from a type that maps to the name
'http://schemas.microsoft.com/xrm/2011/Contracts:ExecuteTransactionRequest'.
The deserializer has no knowledge of any type that maps to this name.
Consider changing the implementation of the ResolveName method on your
DataContractResolver to return a non-null value for name
'ExecuteTransactionRequest' and namespace
'http://schemas.microsoft.com/xrm/2011/Contracts'.'. Please see
InnerException for more details.
CrmConnection connection = CrmConnection.Parse(GetCrmConnectionString("unmanaged"));
IOrganizationService orgService = new OrganizationService(connection);
ExecuteTransactionRequest transactionRequest = new ExecuteTransactionRequest()
{
ReturnResponses = true,
Requests = new OrganizationRequestCollection()
};
Entity newContact = new Entity("contact");
newContact["firstname"] = "Stack";
newContact["lastname"] = "Overflow";
CreateRequest createRequest = new CreateRequest()
{
Target = newContact
};
transactionRequest.Requests.Add(createRequest);
ExecuteTransactionResponse transactionResponse = (ExecuteTransactionResponse)orgService.Execute(transactionRequest);
Update
Quick look at your code, looked like it was because of the CreateRequest not being added to the collection. After your comments and double checking the crm organization version, you are on CRM 2015 (not on update 1). ExecuteTransactionRequest is only supported by CRM 2015 update 1 (version 7.1.XXX) and up (version 8.0.XXX) organizations. So unfortunately, your query won't work until at least the 2015 update is applied to the organization.
You did not add your create request to the ExecuteTransactionRequest - Requests collection. An empty request collection is causing the exceptions most likely.
ExecuteTransactionRequest transactionRequest = new ExecuteTransactionRequest()
{
ReturnResponses = true,
Requests = new OrganizationRequestCollection()
};
Entity newContact = new Entity("contact");
newContact["firstname"] = "Stack";
newContact["lastname"] = "Overflow";
CreateRequest createRequest = new CreateRequest()
{
Target = newContact
};
transactionRequest.Requests.Add(createRequest); //missing
ExecuteTransactionResponse transactionResponse = (ExecuteTransactionResponse)orgService.Execute(transactionRequest);

Can't send custom Slack Message with version 3 of Bot Connector

I have a bot that replies with a message consisting only of attachments. When it works on Slack, it uses Slack attachment formatting quite heavily, thus I have to use ChannelData property.
In version 1 of BotConnector, the code was like this
var reply = message.CreateReplyMessage();
reply.Attachments = new List<Attachment>();
var attachments = new List<object>(); //Slack-formatted attachments
//filling attachments...
reply.ChannelData = new {attachments};
and it worked. Now, in version 3 code has changed to
var reply = activity.CreateReply();
reply.Attachments = new List<Attachment>();
var attachments = new List<object>(); //Slack-formatted attachments
//filling attachments...
reply.ChannelData = new {attachments};
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(reply);
which, basically, boils down to using different method to create reply, and another one to send the reply back.
Now, the problem is, that I don't get the reply back to Slack. Diagnostics in AppInsight show me that somewhere in Connector something like this happens:
Exception type: System.ArgumentNullException
Failed method: SlackChannel.SlackMapper+d__5.MoveNext
Exception Message: value cannot be null. Parameter name: source
ChannelData: {}
message: Invalid ChannelData
Please note that ChannelData in this diagnostics seems to be empty. So what I gather from all this is that something has changed in the way BotConnector processes ChannelData. How can I find out what exactly am I doing wrong?
Actually the problem is inside the ConnectorClient client, which strips channelData. The reason for that lies in its serialization settings which use ReadOnlyJsonContractResolver, which skips all read-only properties - and of course all the properties in anonymous class are read-only.
Knowing that, the solution is quite simple:
reply.ChannelData = JObject.FromObject(new {attachments});
Note the explicit use of JObject instead of anonymous class.

How add attachment into embedded message using EWS

I have a message with ebbedded message, that has own attachment. I have to send this to server using EWS. I can send message with embedded message as attachment, but can't send its attachment, besause AttachmentType doesn't allow add attachment to attachment. Do you know any other ways to solve my problem?
One workaround in that situation that should work is to use the MIMEContent of the ItemAttachment eg
itemAttachment.Load(newPropertySet(ItemSchema.MimeContent));
and then either create a Message based on that or add that as an attachment on a new message eg
FolderId folderid= new FolderId(WellKnownFolderName.Inbox,"MailboxName");
Folder Inbox = Folder.Bind(service,folderid);
ItemView ivItemView = new ItemView(1) ;
FindItemsResults<Item> fiItems = service.FindItems(Inbox.Id,ivItemView);
if(fiItems.Items.Count == 1){
EmailMessage mail = new EmailMessage(service);
EmailMessage OriginalEmail = (EmailMessage)fiItems.Items[0];
PropertySet psPropset= new PropertySet(BasePropertySet.IdOnly);
psPropset.Add(ItemSchema.MimeContent);
psPropset.Add(ItemSchema.Subject);
OriginalEmail.Load(psPropset);
ItemAttachment Attachment = mail.Attachments.AddItemAttachment<EmailMessage>();
Attachment.Item.MimeContent = OriginalEmail.MimeContent;
ExtendedPropertyDefinition PR_Flags = new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer);
Attachment.Item.SetExtendedProperty(PR_Flags,"1");
Attachment.Name = OriginalEmail.Subject;
mail.Subject = "See the Attached Email";
mail.ToRecipients.Add("glen.scales#domain.com");
mail.SendAndSaveCopy();
Cheers
Glen

MS crm Account Creation: System.Net.WebException: The request failed with HTTP status 401: Unauthorized

I am using
I am logged into a remote server for accessing Visual studio as well as MS CRM. I have taken sample code from SDK and trying to run the code:
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = "AdventureWorksCycle";
CrmService service = new CrmService();
service.Url= "http://10.16.16.205:5555/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = new System.Net.NetworkCredential"username", "password", "domain");
// Create the account object.
account account = new account();
// Set the properties of the account object.
account.name = "Fourth Coffee123";
account.address1_line1 = "29 Market St.";
account.address1_city = "Sam";
account.address1_stateorprovince = "MT1";
account.address1_postalcode = "9999";
account.donotbulkemail = new CrmBoolean();
account.donotbulkemail.Value = true;
// Create the target object for the request.
TargetCreateAccount target = new TargetCreateAccount();
// Set the properties of the target object.
target.Account = account;
// Create the request object.
CreateRequest create = new CreateRequest();
// Set the properties of the request object.
create.Target = target;
// Execute the request.
CreateResponse created = (CreateResponse)service.Execute(create);
I am using Crm Web Service for this, but Its throwing exception:
Exception Details:
System.Net.WebException: The request
failed with HTTP status 401:
Unauthorized.
Source Error:
Line 114: [return: System.Xml.Serialization.XmlElementAttribute("Response")]
Line 115: public Response Execute(Request Request) {
Line 116: ***object[] results = this.Invoke("Execute", new object[]* {**
Line 117: Request});
Line 118: return ((Response)(results[0]));
One thing you are missing is a real username and password. I am assuming that you have omitted this for the purposes of this question.
Have you checked the security role on the user that you are using for the web service call? Add this user to the System Administrator role if you haven't already.
With CRM often times, this error has nothing to do with security but something else altogether.
First turn on CRM tracing and look there. This will give you more error detail. Here's how:
http://support.microsoft.com/kb/907490
Also you can try to use my exception formatter to get more detail on the error. This is an extension class that will allow you to format the exception and print it to stdout or to the http response. Find it here:
http://paste.ly/5Y66
Use it this way:
try {
// do all your stuff
} catch (Exception ex) {
ex.Print();
}
Notice that in the formatted exception output, you can see the "Details" property deserialized such that you can see the text version. This is where CRM hides the real exception most of the time.

Resources