c# programmatically reading emails from the Exchange server - c#

When you search on web you will find very easy answers for "How to read emails programmatically"... Al the websites are explaining most of the same like this page.
http://omegacoder.com/?p=454
// depends from Exchange server version
service.Credentials = new NetworkCredential("MDR", "password", "zzz");
service.AutodiscoverUrl("mdr#zzz.be");
object o = service.FindItems(WellKnownFolderName.Inbox, new ItemView(10));
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, new ItemView(10));
foreach (Item item in findResults.Items)
{
Console.WriteLine(item.Subject);
}
it fails when it executes the autodiscoverURL line. The error says "The Autodiscover service couldn't be located."
So I googled further and found this site from Microsoft https://www.testexchangeconnectivity.com/#&&/wEXAQUBcwUBME93h2+JjI0+MV2gTqcRL0g43z9m Here you can test your mail server....
When I pass the parameters I get the error below....
But I still don't understand what the problem is? Do I need to add a record to DNS ? Can someone help?
Attempting to test potential Autodiscover URL https://autodiscover.zzz.be/AutoDiscover/AutoDiscover.xml
Testing of this potential Autodiscover URL failed.
Test Steps
Attempting to resolve the host name autodiscover.ncb.be in DNS.
The host name resolved successfully.
Additional Details
IP addresses returned: 213.246.192.205
Testing TCP port 443 on host autodiscover.ncb.be to ensure it's listening and open.
The specified port is either blocked, not listening, or not producing the expected response.
Tell me more about this issue and how to resolve it
Additional Details
A network error occurred while communicating with the remote host.
Exception details:
Message: No connection could be made because the target machine actively refused it 213.246.192.205:443
Type: System.Net.Sockets.SocketException
Stack trace:
at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)
at Microsoft.Exchange.Tools.ExRca.Tests.TcpPortTest.PerformTestReally()
Attempting to contact the Autodiscover service using the HTTP redirect method.
The attempt to contact Autodiscover using the HTTP Redirect method failed.
Test Steps
Attempting to resolve the host name autodiscover.zzz.be in DNS.
The host name resolved successfully.
Additional Details
IP addresses returned: 213.246.192.205
Testing TCP port 80 on host autodiscover.zzz.be to ensure it's listening and open.
The port was opened successfully.
ExRCA is checking the host autodiscover.zzz.be for an HTTP redirect to the Autodiscover service.
ExRCA failed to get an HTTP redirect response for Autodiscover.
Additional Details
A Web exception occurred because an HTTP 404 - NotFound response was received from IIS7.
Attempting to contact the Autodiscover service using the DNS SRV redirect method.
ExRCA failed to contact the Autodiscover service using the DNS SRV redirect method.
Test Steps
Attempting to locate SRV record _autodiscover._tcp.ncb.be in DNS.
The Autodiscover SRV record wasn't found in DNS.
Tell me more about this issue and how to resolve it

You don't necessarily need to use the autodiscovery if you already know the address of your exchange server. Try the following instead (for more info, look here:
service.Url = new Uri("https://hostname/EWS/Exchange.asmx");
Replace "hostname" with the hostname for your exchange server.

I hope you should have the solution by this time now. This is just to help anyone bumped on this post.
I found the solution on one of the technet article, I twick to suite me, and is working fine for me.
Just replace the line in your code with following:
service.AutodiscoverUrl("user#yourdomain.com",
delegate
{
return true;
});
I had some other issues but not related to this bit though.
Happy Coding,
Sanjay.

I had the same issue with AutoDiscover. It's not necessary, you can specify your URL like
Uri myUri = new Uri("https://Hostname/ews/exchange.asmx");
userData.AutodiscoverUrl = myUri;
service.Url = myUri;
As the hostname you can put the Server IP address like 192.168.100.10
Alternatively, to find what your Exchange server hostname is (in in fact the whole url to use) if you are using Outlook, go to your computer start bar, where the Date and time is showing, you will find the Outlook icon, hold Ctrl + right click on the outlook icon and click “Test Email Auto Configuration”
Check the "Use AutoDiscover" checkbox. Enter an email address hosted on that Exchange Server along with its password and you will recieve a bunch of url's. Use the 1 that says "Availability Service URL"

Consider that the credentials being passed need to have permission to the given exchange mailbox / server. In my case using a different set of credentials that are properly permissioned works but not for a service account which I'm trying to get to work.
Once I discover what exactly the account needs to be permissioned for I will update it here.
Update: My issue was the service account was from a domain different than the domain on which the exchange 2007 instance is running, even though there is a trust relationship between the two. I found this is a documented known issue in Exchange 2007 in how it looks up accounts in its forest. In the end had to create an identical service account (name/pass) on the domain on which the exchange server is sitting and specify username as {exchange_domain}{service_account_name}. The windows service that calls EWS runs as {original_domain}{service_account_name}.
For reference, the exception was:
Microsoft.Exchange.WebServices.Data.ServiceResponseException:
Failed to get valid Active Directory information for the calling account. Confirm that it is a valid Active Directory account.

Related

How to send an email from office365 account using domain windows authentication

I'm developing a console app which will be executed from a windows service that needs to send emails using the domain account associated to the domain account running the windows service.
In my development machine I'm logged with a domain account that belongs to the same domain that will run the windows service but I'm not able to get it working properly.
For this development I'm using .NET 4.6.1 and the nuget package FluentEmail.Smtp
My code looks like this:
Email.DefaultSender = new SmtpSender(new SmtpClient
{
UseDefaultCredentials = true,
EnableSsl = true,
Host = "smtp.office365.com",
TargetName = "STARTTLS/smtp.office365.com",
Port = 587,
DeliveryMethod = SmtpDeliveryMethod.Network
});
await Email.From("myname#mycompanydomain.com", "Some tittle")
.To(emailListObject)
.Subject("Some subject")
.Body("Some body", true)
.SendAsync();
With this code I'm getting the following exception:
Unable to connect to the remote server
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 52.96.9.178:587
at System.Net.Mail.SmtpConnection.ConnectAndHandshakeAsyncResult.End(IAsyncResult result)
at System.Net.Mail.SmtpTransport.EndGetConnection(IAsyncResult result)
at System.Net.Mail.SmtpClient.ConnectCallback(IAsyncResult result)
Note: From my machine I'm able to ping the IP mentioned in the exception
I'll appreciate your assistance
For starters you might want to take a look at the official document - direct send. You will note that there are quite a few issues (such as TLS security) alongside proper configuration of your Exchange server.
Without more information in your question it is rather limited as to what can be answered, however as an alternate solution, maybe take a look at direct send. (which is much less effort).
Settings for direct send
Enter the following settings on the device or in the application directly.
Server/smart host. Use your MX endpoint, for example, contoso-com.mail.protection.outlook.com
Port. Use port 25
TLS/StartTLS. Enable this.
Email address. Use any email address for one of your Office 365 accepted domains. This email address does not need to have a mailbox.
Microsoft recommends adding an SPF record to avoid having messages flagged as spam. If you are sending from a static IP address, add it to your SPF record in your domain registrar's DNS settings as follows:
DNS entry Value
SPF v=spf1 ip4:<Static IP Address> include:spf.protection.outlook.com ~all

How to set certificate in C# Win Application

Im using a webservice in my program.
this is the web service : "https://X.Y.Z.W/ib/ws/openbill.asmx?wsdl"
It works as local. when I write this on Internet Explorer, I can see the proper page after selecting "Continue to this website (not recommended)" in this attachment :
but when I want to access to this, in my c# code, I get this exception :
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
So how can I access this in my c# program?
I think you should first acquire a certificate file, and then use it in your code. For example, to set it for a SMTPClient object:
string certificate = "Certificate.cer";
X509Certificate cert = new X509Certificate2(certificate);
MailMessage message = new MailMessage(from, to);
SmtpClient client = new SmtpClient(server);
client.ClientCertificates.Add(cert);
client.Send(message);
The web service that you are trying to connect to is using SSL/TLS. When you open the web service via internet explorer, it is giving you a warning that it cannot validate the certificate of the web service.
This has many reasons, and I guess in your case it is that the certificate that the web service is using is not for X.Y.Z.W.
Another reason could be that your machine does not trust the root issuer of the web service certificate. But from the error message that you have, I don't think this is the case.
You can view the certificate in IE by click on "Continue on this web site..", and the clicking on "Certificate Error", and the "View certificates".
From there, you will view the certificate. Go to details, and look for DNS Name inside Subject Alternative Name.
The DNS name is the name of the machine that the web service certificate was given for.
I guess in your case it will not be X.Y.Z.W.
Is the web service yours? can you obtain a different certificate for it? If so, can make sure you create a certificate that has the correct DNS name.
As a last resort, you can skip certificate validation from your code (this is not recommended). Take a look at this question.

Microsoft's url for the Exchange powershell schema is not valid anymore

I am trying to create a remote connection to an exchange Powershell hosted on IIS 8.5 - Windows Server 2012 R2.
Here's my code :
var connInfo = new WSManConnectionInfo(
new Uri("https://xxx/PowerShell"),
"http://schemas.microsoft.com/powershell/Microsoft.Exchange",
credentials);
It look like the Microsoft's Schemas url is not valid anymore. If I navigate to http://schemas.microsoft.com/powershell/Microsoft.Exchange, I have this :
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
And when I try to open my connection, I have this error :
Connecting to remote server failed with the following error message : The WinRM client received an HTTP bad request status (400), but the remote service did not include any other information about the cause of the failure.
Is it possible the url changed ? I trid to find a topic about it, but I found no trace of a change...
The schema uri doesn't have to be 'valid' in the sense you don't have to be able to navigate to it. I know I'm not explaining it properly but it's more a reference than a valid location.
The error you're receiving is actually referring to the uri you have for your Exchange Server. If you aren't connecting to an Exchange Server the connection will error.

Credentialed Service Receives 401 Unauthorized from EWS

I have written a windows service in C# to automatically poll an exchange mailbox using EWS.
On my development machine, which is connected to the exchange server network via VPN, it works perfectly.
On the target server the EWS is returning:
Request failed. The remote server returned an error: (401) Unauthorized.(The remote server returned an error: (401) Unauthorized.)
On the same server, I can connect to the EWS URL via a browser using the same credentials as are being provided to the service.
The credentials are provided in the app.config file, and I have triple checked that they are the same on the target server as my development machine.
What could be causing this?
Well as it turned out the issue was that this
_ews.Credentials = new NetworkCredential(Settings.Username, Settings.Password); // Username in the form "domainname\username"
should have been this
_ews.Credentials = new NetworkCredential(Settings.Username, Settings.Password, Settings.Domain); // Domainname and username separate
For some reason the first line worked externally over a VPN but not internally on the domain network itself.

C# code access exchange server without domain name, is that possible?

I'm working on a web application to access exchange server 2010 to get emails from the server. The question is, we don't have domain name for this server. What I know is it's IP address. Is that possible to use Exchange Web Service to access the server? This is my code:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
service.Credentials=new NetworkCredential("StevenZack","123456","208.243.49.20");
//service.AutodiscoverUrl("stevenzack#mail2.local");
service.Url = new Uri("https://208.243.49.20/EWS/Exchange.asmx");
FindItemsResults findResults = service.FindItems(
WellKnownFolderName.Inbox,
new ItemView(10));
foreach (Item item in findResults.Items)
{
div_email.InnerHtml = item.Subject + "<br />";
}
It comes out with an error of "The remote certificate is invalid according to the validation procedure"
How to deal with this situation? Any idea? Thank you for your time!
The SSL warning can be avoiding by setting the ServicePointManager.ServerCertificateValidationCallback delegate (see http://www.infinitec.de/post/2008/11/26/ExchangeWebServices-WebDAV-and-untrusted-server-certificates.aspx).
But this probably won't help you. If you specify 208.243.49.20 you are connecting to the machine using a machine-local account instead of your domain account.
Can you, by any chance, use integrated authentication? You could just impersonate the user and use his credential directly. This way, the user doesn't have to enter his credentials again. Note that you would need to configure Kerberos if your web application resides on a different server as your Exchange server.

Categories