How to save an outlook appointment in users calendar? - c#

I am developing an asp.net web application which allows users to syn any Event from the gridView to there Outlook appointment using the following code:
private void generateOutlookAppointment(string subject, string location, string startDate, string endDate)
{
string body = "Test Data for Body.";
Outlook.Application outlookApp = new Outlook.Application();
Outlook.AppointmentItem oAppointment = (Outlook.AppointmentItem)outlookApp.CreateItem(Outlook.OlItemType.olAppointmentItem);
oAppointment.Subject = subject;
oAppointment.Body = body ;
oAppointment.Location = location;
oAppointment.Start = DateTime.Parse(startDate).AddHours(9);
oAppointment.End = DateTime.Parse(endDate).AddHours(9);
oAppointment.ReminderSet = true;
oAppointment.ReminderMinutesBeforeStart = 15;
oAppointment.Importance = Outlook.OlImportance.olImportanceHigh;
oAppointment.BusyStatus = Outlook.OlBusyStatus.olBusy;
oAppointment.Save();
}
Code works fine when I run locally in visual studio localhost, but fails on server.
Not sure logically would it be able to store an outlook appointment on client outlook since the code is running at server.
Please point me to right direction, even in case I need to use different approach.
Thanks in advance.

Outlook, just like any other Office app, cannot be used in a service (such as IIS).
See How to access client's outlook in ASP.net? for alternatives.

I always did it as an email to the user. A lot of sites online have the required data that needs to be sent to convert an email to a meeting request, here's an example.
http://sahannet.blogspot.com/2010/09/create-outlook-vcalendar-reminder-file.html

Related

How to stop meeting being stripped on forward (EWS)

I am using C# with the Exchange Web Service (EWS).
I have meetings that I need to forward and whenever I do they get stripped, but only from some accounts and not others. The link for the meeting is still there but it is not being recognised by the online Outlook as a meeting item, nor by Teams which is connected to the account.
This even happens if I manually forward, but again only if I forward emails that are from some accounts - some other accounts are fine!
I'm using this on incoming emails:
var fwdEmailArr = new EmailAddress[1];
fwdEmailArr [0] = fwdEmail;
MeetingRequest appointment = MeetingRequest.Bind(service, email.Id);
appointment.Forward("", fwdEmailArr);
This is the same issue if I use the email.forward as well, etc.
However, if I create a new appointment and send it, it doesn't get stripped - this is with the same addresses.
Appointment appt = new Appointment(service);
appt.Subject = email.Subject;
appt.Body = appointment.Body;
appt.Start = appointment.Start;
appt.End = appointment.End;
appt.Location = appointment.Location;
appt.RequiredAttendees.Add(fwdEmail);
foreach (var reqAtt in appt.RequiredAttendees)
{
appt.RequiredAttendees.Add(reqAtt);
}
foreach (var reqAtt in appt.OptionalAttendees)
{
appt.OptionalAttendees.Add(reqAtt);
}
appt.RequiredAttendees.Add(appointment.From.Address);
appt.Save(SendInvitationsMode.SendToAllAndSaveCopy);
So, I could do this but it means that they are no longer the same meeting and declining the original wont decline this. Unless there's a way I can connect the meetings or something?
Any ideas how I can stop the meeting being stripped?
Or alternatively just add another recipient to the current meeting, that will show on their calendar?
If anyone comes here with a similar issue, it turns out that, first of all you need to make sure you define the correct server version on the service declaration:
service = new ExchangeService(ExchangeVersion.Exchange2016){}
In addition, for some reason some images when attached to the forwarded email for some reason confuse EWS and make it think there's no meeting. I got around this by scanning the MIME content and just extracting the calendar block and deleting all other attachments.
This has been working flawlessly for about 5 months.

How to remove "on behalf of " while sending mail from C# using Microsoft.Office.Interop.Outlook

This is shared Mailbox that is given access to my email for sending and receiving mails. However when I send the mails via outlook from shared mail box I am not getting the "on behalf of" message whereas when I send it from code I am getting as MyEmail.com on behalf of sharedEmail.com.
var app = new Application();
MailItem mailItem = app.CreateItem(OlItemType.olMailItem);
mailItem.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
var attachments = mailItem.Attachments;
mailItem.Subject = item.Capability + " - " + appSettings["Subject"].ToString();
mailItem.HTMLBody = CreateBody(appSettings);
mailItem.CC= appSettings["CCEmails"].ToString();
mailItem.Recipients.Add(appSettings["FromAddress"]);
mailItem.Recipients.ResolveAll();
var adressEntry = mailItem.Recipients[mailItem.Recipients.Count].AddressEntry;
mailItem.Recipients.Remove(mailItem.Recipients.Count);
mailItem.Sender = adressEntry;
mailItem.To = item.EmailId;
mailItem.Importance = OlImportance.olImportanceHigh;
mailItem.Send();
ReleaseObj(app);
Following Things I have already Tried.
1.Using SendUsingAccount -This did not work since the mail is configured as shared mailbox and not as shared account so this mailbox is not listing under the accounts.
2.Using SentOnBehalfOfName-This also is not working , I followed one of the stack overflow user workaround approach to set the sender name.
3.Many of the answers are suggesting to enable "Send As" or "Behalf of" Permissions from the admin but if permissions is the issue why I am getting the message "on behalf of " only through code and not via outlook client.
Thanks in advance for help
You have:
mailItem.Sender = adressEntry;
But seem to be missing the From Address, I haven't tried but adding these lines may override the "on behalf of":
EmailAddress fromSender = new EmailAddress();
fromSender.Address = _sharedOutlookMailAccount;
message.From = fromSender;
Ref: How to send email via a Shared MailBox using Exchange Web Services (EWS) API

Create appointments in Outlook calenders of employees using C# and Exchange 2019

I can't show any code here yet, because i'm still analyzing if it is possible to realize this.
In our company we have a virtual system to make and manage leave applications. I should now check if it would be possible to enter an approved vacation in the Outlook calendar of the applicant.
I would need a central solution which remotely accesses the calendar and enters the appointments. We currently use the on premise solution of Mircosoft Exchange 2019 and Office 365.
During my research I came across EWS but it seems that Exchange 2019 does not support it anymore. Is there possibly another solution which I could use? Basically I would like to realize a solution with C# but I would also be able to realize a Powershell or Java solution. But most of the time I did not find a real solution.
Most of the time the examples are always local on the machines or using an older Exchange Server like 2013. I haven't found reliable information for 2019 yet. I hope someone here can help me or give me a hint. Or it would also be helpful to say if it is not possible.
Best regards!
I am currently working on a solution. I will post the code when I am successfull!**
Exchange 2019 fully supports EWS.
EWS is still the preferred API to access Exchange, even if Microsoft is not adding any new features to it.
ON the client side, you can use Outlook Object Model and its Namespace.GetSharedDefaultFolder methods. Once you have an instance of the MAPIFolder object, you can use MAPIFolder.Items.Add to create a new appointment.
I did choose a little bit different approach but I was able to make it fully work. I now can create events and delete them if needed.
public void UpdateCalender()
{
ExchangeService Service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
Uri Url = new Uri("https://localmaildomain.sys/EWS/Exchange.asmx");
Service.Url = Url;
Service.Credentials = new NetworkCredential("service_user","service_password");
Folder inboxFolder = Folder.Bind(Service, new FolderId(WellKnownFolderName.Calendar, Temp.UserMail));
foreach (var entry in Temp.Positions)
{
if (!entry.Storno)
{
try
{
Appointment appointment = new Appointment(Service);
appointment.Subject = $"Urlaub/Vacation ({entry.Type})";
appointment.Body = $"{entry.Comment}";
appointment.IsAllDayEvent = true;
appointment.Start = entry.Date.AddSeconds(1);
appointment.End = entry.Date.AddSeconds(1);
appointment.LegacyFreeBusyStatus = LegacyFreeBusyStatus.OOF;
appointment.Save(inboxFolder.Id, SendInvitationsMode.SendToNone);
}
catch (Exception Ex)
{
Console.WriteLine($"Calender item could not be created! Exception: {Ex.ToString()}");
}
}
else
{
CalendarView view = new CalendarView(entry.Date, entry.Date);
FindItemsResults<Appointment> results = Service.FindAppointments(inboxFolder.Id,view);
foreach (var appointment in results)
{
if (appointment.Subject == $"Urlaub/Vacation ({entry.Type})" && appointment.Start == entry.Date)
{
try
{
appointment.Delete(DeleteMode.MoveToDeletedItems);
}
catch(Exception Ex)
{
Console.WriteLine($"Calender item could not be deleted! Exception: {Ex.ToString()}");
}
break;
}
}
}
}
}

ExchangeService: connecting without credentials, how to retrieve user information?

I am analyzing a users Exchange mailbox with calls to the ExchangeService. This tool needs to run on the client environment periodically and by ommiting the credentials to the service I am connecting to the Exchange Service as the logged in Windows User. I can succesfully loop thrue the folders and items.
Now I want tot retrieve the information about the mailbox being used. Username and (main) E-mail should suffice. But I cannot find anything about how to retrieve this information. Every example provides credentails for the user, or auto-discovering the Exchange service from the e-mail adres. I do not want the user to configure anything :-).
Any suggestions?
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Url = new Uri("https://FQDN/EWS/Exchange.asmx");
???
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.SentItems, new ItemView(100)); // this works
I've tried using service.ResolveName, but that can give multiple answers, even using Environment.UserName
The easiest method to do this is to use ConvertId operation and use unresolvable address (blah#blah.com always works for me) in the Mailbox element. Exchange should convert this to the actual Mailbox in the response. eg
Folder chk = Folder.Bind(service, WellKnownFolderName.Inbox);
AlternateId aiItem = new AlternateId();
aiItem.Mailbox = "Blah#Blah.com";
aiItem.UniqueId = chk.Id.UniqueId;
aiItem.Format = IdFormat.EwsId;
String CasServer = service.Url.Host.ToString();
AlternateIdBase caid = service.ConvertId(aiItem, IdFormat.HexEntryId);
Console.WriteLine(((AlternateId)caid).Mailbox);
Cheers
Glen

Creating New Message with default signature using Exchange Web Services

Currently a piece of our application creates and saves new mail messages to a user's drafts folder using Exchange Web Services. We would like to automatically append the user's default signature to these messages when creating them, but I have not been able to find a way to access the signature to append it to the body. The email message is currently created with the following code:
CreateItemType createEmailRequest = new CreateItemType();
createEmailRequest.MessageDisposition = MessageDispositionType.SaveOnly;
createEmailRequest.MessageDispositionSpecified = true;
DistinguishedFolderIdType draftsFolder = new DistinguishedFolderIdType();
draftsFolder.Id = distinguishedFolderIdNameType;
createEmailRequest.SavedItemFolderId = new TargetFolderIdType();
createEmailRequest.SavedItemFolderId.Item = draftsFolder;
MessageType emailMessage = new MessageType();
emailMessage.Subject = subject;
emailMessage.Body = new BodyType();
emailMessage.Body.BodyType1 = bodyType;
emailMessage.Body.Value = body;
emailMessage.Sensitivity = SensitivityChoicesType.Normal;
emailMessage.SensitivitySpecified = true;
createEmailRequest.Items = new NonEmptyArrayOfAllItemsType();
createEmailRequest.Items.Items = new ItemType[1];
createEmailRequest.Items.Items[0] = emailMessage;
Any ideas on how to get the current user's default signature and append it to the body the email?
The signatures in Outlook are a client-side feature and thus can't be accessed from Exchange Web Services. In fact I believe the signatures are actually stored in the users profile on the machine - I know I have to redo my signature when moving from one machine to another (I'm on Outlook/Exchange 2010).
In Exchange 2010 You can create a transport rule that can access user information, but there's not a way to use the Outlook signature information that I'm aware of.

Categories

Resources