Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / Azure

Enterprise Web Services in Azure

1.80/5 (2 votes)
24 May 2016CPOL3 min read 12K  
Running Enterprise web services in Azure

Introduction

This article talks about the tips/tricks involved while integrating email services in your web application using Enterprise Web Services(EWS). If you are planning to host your application in Azure by implementing your organizations email configurations, then this is one of the best approaches. There is an agile nature of maintaining these kind of practices in a hosted Azure solution.For example, your enterprise uses Office 2007 exchange server and because of their recent migrations to exchange server 2013 with an Office 365 implementation, their application configurations may not work. In this scenario, with a new service URL reference and a small change in your email sending source code can start your email services in Azure environment.

Background

In your legacy .NET web applications, you might have used different kind of email libraries for sending emails. This works really great when you are building an on premise web application where hosting need is maintained on premise datacenter. Enterprises were using Office exchange server 2007, 2007 sp1, 2010 exchange server, etc, but when the cloud scenario came to the market, giants like Google, Microsoft put their brains into this business and made some great frameworks to maintain all your Office stuff in a single place where you can access them from your IPad, Mobile. Within your enterprise firewall boundary. Google named them Google drive with minimal features but, when Microsoft came to this space, they have introduced the same concept like Google did in Google Drive but with better Office management. Organizations that are using exchange server 2007 or 2010 are more likely to love this way of Office representation. They have started migrating their office apps to Office 365. This kind of strategy hurt our developers a lot because when a traditional web application is shipped to Windows Azure, then the developer has to do some research to migrate everything to Windows Azure. Again, when the small mind (Developer) came to know that Office 365 integrations are up and running in enterprise, they started biting their nails.

 

Some folk saints came to their dream and told them they heard about Microsoft exchange web services which can solve their issue. Developer ran to his workplace with this idea and started R&D on Exchange web services and he/she has found that this can help them to run Office 365/any exchange email services in Azure. He explored the below code snippets.

Using the Code

To use Microsoft exchange web services, please add a service reference. You have to add the WSDL URL to configure the web service.

Your Office 365 URL will look like below:

https://podsomedigits.outlook.com/EWS/Services.wsdl

The bold one will be a unique tenant id.

Once you add the web services, click on the property of added service reference and make the url behavior ‘Dynamic’.

Now write a reusable class which can be used for sending emails.

In the below Email Manager Class abcd stands for namespace.

Now your Exchange configurations in Web.config shall be listed as below:

ASP.NET
<add key="FromEmail" value="cpadmin@codeproject.com" />
<add key="EchangeUser" value="cpadmin@codeproject.com" />
<add key="ExchangePassword" value="password123" />
<add key="ExchangeDomain" value="cfi" />
<add key="ExchangeServiceUrl" value="https://podsomedigits.outlook.com/EWS/Exchange.asmx" />

Please don’t copy paste. The above configurations value is for your understanding.

esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2013_SP1;

The above line is really agile. Now in future if Microsoft comes with Exchange2014, then once you reconfigure your web reference, you can get the required exchange version type. If your enterprise will degrade exchange server, then also you can change this type. Degradation never happens!

Email Manager Class

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using abcd.DTO;
using abcd.ExchangeWebServices;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
namespace abcd
{
public static class EmailManager
{
public static string SendMail(EmailDTO emailContent)
{   string returnMsg = string.Empty;
    string userName = ConfigurationManager.AppSettings["EchangeUser"].ToString();
    string password = ConfigurationManager.AppSettings["ExchangePassword"].ToString();
    string domain = ConfigurationManager.AppSettings["ExchangeDomain"].ToString();
    string serviceUrl = ConfigurationManager.AppSettings["ExchangeServiceUrl"].ToString();
    string fromEmail = ConfigurationManager.AppSettings["FromEmail"].ToString();
ServicePointManager.ServerCertificateValidationCallback = 
delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
   // Replace this line with code to validate server certificate.
    return true;
};
// Identify the service binding and the user.
ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.Credentials = new NetworkCredential(userName, password, domain);
esb.Url = serviceUrl;
// Specify the request version.
esb.RequestServerVersionValue = new RequestServerVersion();
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2013_SP1;
// Create the CreateItem request.
CreateItemType createEmailRequest = new CreateItemType();
// Specify how the e-mail will be handled.
createEmailRequest.MessageDisposition = MessageDispositionType.SendAndSaveCopy;
createEmailRequest.MessageDispositionSpecified = true;
// Specify the location of sent items.
createEmailRequest.SavedItemFolderId = new TargetFolderIdType();
DistinguishedFolderIdType sentitems = new DistinguishedFolderIdType();
sentitems.Id = DistinguishedFolderIdNameType.sentitems;
createEmailRequest.SavedItemFolderId.Item = sentitems;
// Create the array of items.
 createEmailRequest.Items = new NonEmptyArrayOfAllItemsType();
// Create a single e-mail message.
MessageType message = new MessageType();
message.Subject = emailContent.Subject;
message.Body = new BodyType();
message.Body.BodyType1 = BodyTypeType.HTML;
message.Body.Value = 
emailContent.Body; //"(1) Handled customer issues, </Br> (2) Saved the world.";
message.Sender = new SingleRecipientType();
message.Sender.Item = new EmailAddressType();
message.Sender.Item.EmailAddress = fromEmail;
if (emailContent.ToRecipientsEmail != null)
 {
   message.ToRecipients = new EmailAddressType[emailContent.ToRecipientsEmail.Count];
   for (int index = 0; index < emailContent.ToRecipientsEmail.Count; index++)
{
message.ToRecipients[index] = new EmailAddressType();
message.ToRecipients[index].EmailAddress = emailContent.ToRecipientsEmail[index];
 }
 }
if (emailContent.CcRecipientsEmail != null)
 {
message.CcRecipients = new EmailAddressType[emailContent.CcRecipientsEmail.Count];
for (int index = 0; index < emailContent.CcRecipientsEmail.Count; index++)
 {
message.CcRecipients[index] = new EmailAddressType();
message.CcRecipients[index].EmailAddress = emailContent.CcRecipientsEmail[index];
 }
 }
if (emailContent.BccRecipientsEmail != null)
{
message.BccRecipients = new EmailAddressType[emailContent.BccRecipientsEmail.Count];
 for (int index = 0; index < emailContent.BccRecipientsEmail.Count; index++)
 {
message.BccRecipients[index] = new EmailAddressType();
message.BccRecipients[index].EmailAddress = emailContent.BccRecipientsEmail[index];
 }
}
message.Sensitivity = SensitivityChoicesType.Normal;
// Add the message to the array of items to be created.
createEmailRequest.Items.Items = new ItemType[1];
createEmailRequest.Items.Items[0] = message;
// Send a CreateItem request and get the CreateItem response.
CreateItemResponseType createItemResponse = esb.CreateItem(createEmailRequest);
ArrayOfResponseMessagesType responses = createItemResponse.ResponseMessages;
ResponseMessageType[] responseMessages = responses.Items;
// Access the response messages.
foreach (ResponseMessageType respMsg in responseMessages)
{
if (respMsg.ResponseClass == ResponseClassType.Error)
{
  //throw new Exception("Error: " + respMsg.MessageText);
   returnMsg = "Error: " + respMsg.MessageText;
   return returnMsg;
}
else if (respMsg.ResponseClass == ResponseClassType.Warning)
{
//throw new Exception("Warning: " + respMsg.MessageText);
 returnMsg = "Warning: " + respMsg.MessageText; 
return returnMsg;
 }
}
returnMsg = "Mail Sent Successfully";
return returnMsg;
}
private static bool CertificateValidationCallBack(object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
 if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
  return true;
 }
 // If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
 if (chain != null && chain.ChainStatus != null)
 {
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
{
if ((certificate.Subject == certificate.Issuer) && 
(status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
{
// Self-signed certificates with an untrusted root are valid.
continue;
}
else
{
if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
{
// If there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
return false;
}
}
 }
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange Server installations, so return true.
return true;
}
else
{
// In all other cases, return false.
return false;
}
}
}
}

DTO Class

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace abcd.DTO
{
public class EmailDTO
{
 public virtual string Subject { get; set; }
public virtual string Body { get; set; }
public virtual List<string> ToRecipientsEmail { get; set; }
public virtual List<string> CcRecipientsEmail { get; set; }
public virtual List<string> BccRecipientsEmail { get; set; }
}
}

Calling Time

C#
EmailDTO objEmail = new EmailDTO();
objEmail.ToRecipientsEmail = from your To textbox;
 objEmail.CcRecipientsEmail = From your CC textbox;
objEmail.BccRecipientsEmail = From your BCC textbox;
objEmail.Subject = subject;
 objEmail.Body = body;
string retMsg = EmailManager.SendMail(objEmail); 
if (retMsg.ToUpper().Contains("ERROR") || 
	(retMsg.ToUpper().Contains("WARNING")))
{
  Logging.LogError(retMsg);
//Show error message
ShowMessage(retMsg, "message_error");
}
else
{
//show success message
ShowMessage(retMsg, "message_success");
}

Apart from this mail functionality, you can consume lots of other Office 365 services from this exchange web services.

Points of Interest

This kind of source code for using email services really helped us because when our client changed the exchange server from 2007 to 2013, it was helpful for us to maintain the services by changing a single line of code.

C#
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;

to:

C#
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2013_SP1;

References

  1. http://msdn.microsoft.com/en-us/library/office/bb408521%28v=exchg.140%29.aspx
  2. http://msdn.microsoft.com/en-us/library/office/dd633677%28v=exchg.80%29.aspx
  3. http://msdn.microsoft.com/en-us/library/office/aa563009%28v=exchg.140%29.aspx

History

  • 24th May, 2016: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)