Good day,
I have run into an issue that could either be an incorrect setup of Exchange or the code that I am using, but cannot determine which is wrong. I am trying to send an email from an Exchange email account from an Asp.Net Core application. The AutodiscoverConfiguration Request and Response are showing the correct trace information. The EWS Request is showing the correct trace information, but the EWS Response does not.
Here is the output of the EWSResponseHttpHeaders:
<?xml version="1.0" encoding="utf-16"?><Trace Tag="EwsResponseHttpHeaders" Tid="13" Time="2020-06-05 15:28:01Z"> HTTP/1.1 200 OK Cache-Control: no-store, no-cache Pragma: no-cache Server: Microsoft-IIS/10.0 request-id: d78a4945-e42f-4013-b078-c29b82b24e9e X-Frame-Options: SAMEORIGIN X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 05 Jun 2020 15:28:00 GMT Content-Type: text/html; charset=utf-8 Expires: -1 Content-Length: 58732</Trace>
Here is the output of the EWSResponse:
System.IO.MemoryStream
Here is the output of the EWSRequest:
<?xml version="1.0" encoding="utf-16"?><Trace Tag="EwsRequest" Tid="9" Time="2020-06-05 15:28:00Z" Version="15.0.913.15"><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><t:RequestServerVersion Version="Exchange2016" /><t:ExchangeImpersonation><t:ConnectingSID><t:SmtpAddress>Administrator@mydomain.com</t:SmtpAddress></t:ConnectingSID></t:ExchangeImpersonation></soap:Header><soap:Body><m:CreateItem MessageDisposition="SendAndSaveCopy"><m:SavedItemFolderId><t:DistinguishedFolderId Id="sentitems" /></m:SavedItemFolderId><m:Items><t:Message><t:Subject>Test email from Controller</t:Subject><t:Body BodyType="HTML">This is a test email being sent from the Weather Forcast Controller on Get</t:Body><t:ToRecipients><t:Mailbox><t:EmailAddress>myuser@gmail.com</t:EmailAddress></t:Mailbox></t:ToRecipients><t:From><t:Mailbox><t:EmailAddress>Administrator@mydomain.com</t:EmailAddress></t:Mailbox></t:From></t:Message></m:Items></m:CreateItem></soap:Body></soap:Envelope></Trace>
Here is my SendEmail code:
public class ExchangeEmailSender : IExchangeEmailSender { private readonly EmailConfiguration _emailConfiguration; //private readonly ExchangeService _service = new ExchangeService(ExchangeVersion.Exchange2016); //Construct with the readonly of configuration, which will be passed in on setup. public ExchangeEmailSender(EmailConfiguration emailConfiguration) { _emailConfiguration = emailConfiguration; } //Takes an instance of ExchangeMessage(IEnumerable<string> mailTo, string subject, string content) public virtual string SendEmail(ExchangeMessage message) { //Get a message to send var emailMessage = CreateEmailMessage(message); //Send email emailMessage.SendAndSaveCopy(); var result = "An email with the subject '" + emailMessage.Subject + "' has been sent to the following recipients '" + emailMessage.ToRecipients[0] + "'."; return result; } //Takes an instance of ExchangeMessage(IEnumerable<string> mailTo, string subject, string content) private EmailMessage CreateEmailMessage(ExchangeMessage message) { //Get the user sending the email var user = _emailConfiguration.From; var password = _emailConfiguration.Password; var domain = "mydomain"; //Initiate the service for Exchange var service = new ExchangeService(ExchangeVersion.Exchange2016) { Credentials = new NetworkCredential(user, password, domain), ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "Administrator@mydomain.com"), UseDefaultCredentials = true, TraceListener = new ExchangeTraceListener(), TraceEnabled = true, TraceFlags = TraceFlags.All }; //Pass in the user that is sending service.AutodiscoverUrl(user, URLRedirection.RedirectionUrlValidationCallBack); Folder.Bind(service, WellKnownFolderName.SentItems); //Create a new EmailMessage to send using the service var emailMessage = new EmailMessage(service); emailMessage.From = new EmailAddress(); emailMessage.From.Address = user; emailMessage.ToRecipients.AddRange(message.MailTo); emailMessage.Subject = message.Subject; emailMessage.Body = new TextBody() { Text = message.Content }; //Pass the message back to where it is called from return emailMessage; } }
Here is how it is being used in the controller:
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] {"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; private readonly IExchangeEmailSender _exchangeEmailSender; public WeatherForecastController(ILogger<WeatherForecastController> logger, IExchangeEmailSender exchangeEmailSender) { _logger = logger; _exchangeEmailSender = exchangeEmailSender; } [HttpPost] public async Task<IEnumerable<WeatherForecast>> Post() { var rng = new Random(); var message = new ExchangeMessage(new string[] { "myuser@gmail.com" }, "Test email from Controller", "This is a test email being sent from the Weather Forcast Controller on Get"); _exchangeEmailSender.SendEmail(message); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }
Now it looks like everything is working as Postman is giving a 200 Ok on Post, but I know it is not sending the email and it is not placing it in the sent items folder. I also do have the following rule set up in Exchange:
Get-ManagementRoleAssignment -RoleAssignee "IdentityImpersonation" | fl RunspaceId : 570467f1-adeb-4888-882c-9158e7435495 DataObject : ApplicationImpersonation-IdentityImpersonation User : mydomain.com/Microsoft Exchange Security Groups/IdentityImpersonation AssignmentMethod : Direct Identity : ApplicationImpersonation-IdentityImpersonation EffectiveUserName : All Group Members AssignmentChain : RoleAssigneeType : RoleGroup RoleAssignee : mydomain.com/Microsoft Exchange Security Groups/IdentityImpersonation Role : ApplicationImpersonation RoleAssignmentDelegationType : Regular CustomRecipientWriteScope : CustomConfigWriteScope : RecipientReadScope : Organization ConfigReadScope : None RecipientWriteScope : Organization ConfigWriteScope : None Enabled : True RoleAssigneeName : IdentityImpersonation IsValid : True ExchangeVersion : 0.11 (14.0.550.0) Name : ApplicationImpersonation-IdentityImpersonation DistinguishedName : CN=ApplicationImpersonation-IdentityImpersonation,CN=Role Assignments,CN=RBAC,CN=My Domain ,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=MyDomain,DC=com Guid : a3df5cb9-9e34-48c5-82b0-d3f221e50387 ObjectCategory : Mydomain.com/Configuration/Schema/ms-Exch-Role-Assignment ObjectClass : {top, msExchRoleAssignment} WhenChanged : 6/5/2020 8:33:37 AM WhenCreated : 6/5/2020 8:33:16 AM WhenChangedUTC : 6/5/2020 12:33:37 PM WhenCreatedUTC : 6/5/2020 12:33:16 PM OrganizationId : Id : ApplicationImpersonation-IdentityImpersonation OriginatingServer : DC2.mydomain.com ObjectState : Unchanged
This shows Members as Administrator.
For my Exchange Web Services I am using the following from Nuget: Microsoft.Exchange.WebServices.NETStandard version 1.1.3 (). So I do not know where I have gone wrong, anyone have any thoughts as to why it is not sending an email?
Michael R. Mastro II