SPUtility.SendEmail() always returns false - c#

I have one application which will create task form for each level based on the prior level approval. While creating each tasks I have to send the email to the users who all are involved in the task. For this I am using SPUtility.SendEmail() method. But unfortunately, it didn't work so far. The debugger successfully passed through the SendEmail method without any exception. but the value will always false. The SMTP server is working for the application other than the SP Applications. My code is shown below.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite spSite = new SPSite(SiteURL))
{
using (SPWeb spWeb = spSite.OpenWeb())
{
headers = new StringDictionary();
headers.Add("to", To);
headers.Add("from", From);
headers.Add("cc", CC);
headers.Add("bcc", BCC);
if (Priority.Equals("High"))
{
headers.Add("X-Priority", "1 (Highest)");
headers.Add("X-MSMail-Priority", "High");
headers.Add("Importance", "High");
}
headers.Add("subject", Subject);
headers.Add("content-type", "text/html");
Status = SPUtility.SendEmail(spWeb, true, true, To, Subject, Body);
}
}
});
Please help me to resolve this issue. All Suggestions would be appreciated. Thanks in advance.

I had the same problem a few minutes ago.
You might have a problem with smtp server RELAY.
Try this:
Open IIS 6.
Go To SMTP Virtual Server (Open properties)
Tab General: Select IP adddress of the server in the dropdown
Tab Access:
4.1 In Access Control ensure anonymous access is checked
4.2 In Relay Restrictions add IP: 127.0.0.1 and IP address of the server
Tab Delivery: Go to button "Outbound Connections" and set port = 587
that´s all.
I hope helpfull

It looks to me like you're using the wrong method signature. You're going to the trouble of setting up headers as a StringDictionary, but then you're using the overload of SPUtility.SendEmail() that doesn't use those headers.
Try this instead:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite spSite = new SPSite(SiteURL))
{
using (SPWeb spWeb = spSite.OpenWeb())
{
headers = new StringDictionary();
headers.Add("to", To);
headers.Add("from", From);
headers.Add("cc", CC);
headers.Add("bcc", BCC);
if (Priority.Equals("High"))
{
headers.Add("X-Priority", "1 (Highest)");
headers.Add("X-MSMail-Priority", "High");
headers.Add("Importance", "High");
}
headers.Add("subject", Subject);
headers.Add("content-type", "text/html");
Status = SPUtility.SendEmail(spWeb, headers, Body);
}
}
});

Related

Read an office 365 mailbox using Exchange web services

I am using this below code but unable to read my office 365 Inbox emails from C# code. Once I get this working then later I would need to read emails from shared mailbox.
I’d really appreciate if someone could please help me in fixing this issue or guide me what am I missing here ?
If I use Url as Office365 one then getting this error: "The request failed. The remote server returned an error 401. Unauthorized "
If I use Url as casx16 one (found this in company's Q/A portal) then getting this error: " No mailbox with such GUID "
using Microsoft.Exchange.WebServices.Data;
public static void ReadMyMailbox_2()
{
ExchangeService exchangeService = new ExchangeService();
exchangeService.Credentials = new WebCredentials("ajain", "password ", "MS"); /// ajain is my MSID
// exchangeService.AutodiscoverUrl("a_jain#xyz.com", RedirectionUrlValidationCallback);
exchangeService.Url = new Uri("https://casx16.xyz.com/ews/exchange.asmx");
// exchangeService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
FolderId mailbox = new FolderId(WellKnownFolderName.Inbox, "a_jain#xyz.com");
ItemView itemView = new ItemView(10);
FindItemsResults<Item> result = exchangeService.FindItems(mailbox, itemView);
foreach (var msg in result)
{
EmailMessage message = EmailMessage.Bind(exchangeService, msg.Id);
Console.WriteLine(message.Subject);
}
}
It looks like you're setting up the ExchangeService object correctly. A couple things to try:
Try passing the full email (a_jain#xyz.com) to WebCredentials
Make sure your the domain you're passing to WebCredentials is correct
Try the WebCredentials constructor that only takes username and password.
Note: I don't think autodiscover will work with O365

C# Console Application - Parsing Office 365 Inbox

I was able to succeed via a package I found called EAGetMail. Unfortunately, I realized soon after that they have a token system and this is not a free approach.
There are a couple other choices available, like using Outlook Mail REST API, and MimeKit, but I'm lost on how to achieve my end result because no "start to finish" code is available on either of these references that demonstrates how to parse an Inbox for an account.
I've started to write this with the help of Mimekit, but am not sure if this is the proper way at all.
I must imagine it looks something like:
using (var client = new SmtpClient ())
{
client.Connect("outlook.office365.com", 587);
client.Authenticate("myemail#office365account.com", "mypassword");
var message = MimeMessage.Load(stream);
}
I don't know how to setup the stream mentioned above, and I don't know if it's possible to do this with Mimekit and Office 365.
I'm open to seeing a solution for this in any other approach that's not through EAGetMail. If anyone has a lightweight solution ranging from actual establishing a connection, to pulling messages from the inbox, would be great to see!
I've got it using EWS (Exchange Web Services). Here's my code:
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
static void Main(string[] args)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials("email#myemail.com", "myPassword");
service.AutodiscoverUrl("email#myemail.com", RedirectionUrlValidationCallback);
//creates an object that will represent the desired mailbox
Mailbox mb = new Mailbox(#"email#myemail.com");
//creates a folder object that will point to inbox folder
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);
//this will bind the mailbox you're looking for using your service instance
Folder inbox = Folder.Bind(service, fid);
//load items from mailbox inbox folder
if (inbox != null)
{
FindItemsResults<Item> items = inbox.FindItems(new ItemView(100));
foreach (var item in items)
{
item.Load();
Console.WriteLine("Subject: " + item.Subject);
}
}
}

How to send mails using SmtpClient and DefaultNetworkCredentials to a distribution list that only allows authenticated senders?

I'm trying to send automated emails from a C# console application from machines to clients all on the same domain via our internal Exchange 2007 server (using SMTP), but I'm hitting a snag with distribution lists that only allow authenticated senders. Basically the mails I'm sending are getting rejected by Exchange with:
#550 5.7.1 RESOLVER.RST.AuthRequired; authentication required ##rfc822;AuthTESTGroup#example.com
I'm using System.Net.Mail.SmtpClient and setting the Credentials property to System.Net.CredentialCache.DefaultNetworkCredentials, but somewhere along the line, the credentials of the account running this program (me, a valid domain user with a valid mailbox) are not getting passed down to Exchange correctly.
I'm using System.Net.CredentialCache.DefaultNetworkCredentials because I do not want to hard code a username or password (either in the code itself or in any sort of configuration file); I want the process to authenticate with our SMTP server using Windows authentication.
Here is a test program I've been using to reproduce the problem (domain names have been anonomized):
using System;
using System.Net.Mail;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var smtpClient = new SmtpClient
{
Host = "MAIL",
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = System.Net.CredentialCache.DefaultNetworkCredentials
};
var mailMessage = new MailMessage
{
Body = "Testing",
From = new MailAddress(Environment.UserName + "#example.com"),
Subject = "Testing",
Priority = MailPriority.Normal
};
mailMessage.To.Add("AuthTESTGroup#example.com");
smtpClient.Send(mailMessage);
}
}
}
Whenever I run this as myself (again, I'm a valid user on the domain, with an existing mailbox on the Exchange server) I get an undeliverable bounce message from Exchange with the response:
#550 5.7.1 RESOLVER.RST.AuthRequired; authentication required ##rfc822;AuthTESTGroup#example.com
I talked to our Exchange server admin and he saw the following error from the Exchange server's event log:
Account For Which Logon Failed:
Security ID: NULL SID
Account Name:
Account Domain:
Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xc000006d
Sub Status: 0xC0000064
Apparently that status code and sub status code translate to:
0xc000006d This is either due to a bad username or authentication information. Usually logged as status code with 0xc0000064 as substatus
0xC0000064 user name does not exist
So again, it's as if somewhere along the line, my Windows credentials are not getting passed down to the Exchange server even though I'm setting the SmtpClient.Credentials to System.Net.CredentialCache.DefaultNetworkCredentials
Any ideas?
Thanks in advance!
you need to pass username, password
here is a code snippet of how I would do it... keep in mind this is a code snippet you need to make the necessary changes to fit your Use Case
MailClient = new SmtpClient();
MailClient.Credentials = new System.Net.NetworkCredential(username, password);
below is another example but uses the server variable.. this maybe what you need to do try and let me know the server for example you can pass as your domain.com
example :
//SmtpClient client = new SmtpClient("smtp.contoso.com");//this would be server
//client.Credentials = CredentialCache.DefaultNetworkCredentials;
public static void CreateBccTestMessage(string server)
{
MailAddress from = new MailAddress("ben#contoso.com", "Ben Miller");
MailAddress to = new MailAddress("jane#contoso.com", "Jane Clayton");
MailMessage message = new MailMessage(from, to);
message.Subject = "Using the SmtpClient class.";
message.Body = #"Using this feature, you can send an e-mail message from an application very easily.";
MailAddress bcc = new MailAddress("manager1#contoso.com");
message.Bcc.Add(bcc);
SmtpClient client = new SmtpClient(server);
client.Credentials = CredentialCache.DefaultNetworkCredentials;
Console.WriteLine("Sending an e-mail message to {0} and {1}.",
to.DisplayName, message.Bcc.ToString());
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in CreateBccTestMessage(): {0}",
ex.ToString());
}
}

Permission issues when trying to send email via SMTP from ASP.NET page

I have done this before without any issue but now I don't know what's wrong. I have a web page with a button for email which I want to send some data to email addresses with.
I asked our web hosting company for server details and the response I got was:
"You can use the following details for mail.
Incoming mail server: mail.ourSite.com Outgoing mail server: mail.ourSite.com
Username and password are the email address and password associated with the email address.
"
I am not sure about the last line but I created a new email address in the web host's control panel.
The code I use is:
// instantiate a new mail definition and load an html
// template into a string which I replace values in
// then the rest of the code below
md.Subject = String.Format("{0} {1} {2}", emailSubject, firstName, lastName);
MailMessage msg = md.CreateMailMessage(emailAddress, replacements, emailBody, new Control());
md.IsBodyHtml = true;
SmtpClient sc = new SmtpClient(emailServer);
sc.Credentials = new NetworkCredential(emailUsername, emailPassword);
try
{
sc.Send(msg);
}
emailServer - mail.ourSite.com (dummy value in this post)
emailUsername - the email address I created in the control panel
emailPassword - the password for the email above
The error I have is that when I send emails to other domains than our own I get
"Bad sequence of commands. The server response was: This mail server requires authentication when attempting to send to a non-local e-mail address. Please check your mail client settings or contact your administrator to verify that the domain or address is defined for this server."
When I email to an address within our host then it works fine.
The support is not very supportive so I am asking here what you might think the problem could be? I find it strange that I use the password for an email address I created, should it really be like that?
I think that you are using the wrong email address for the NetworkCredential. It should be the one for your email account that you got from the one providing emailServer.
Try this ..
msg.UseDefaultCredentials = false;
NetworkCredential MyCredential = new NetworkCredential("Email", "Password");
msg.Credentials = MyCredential;
here is code to send mail..
i hope i will helpful to you..
using System.Web.Mail;
using System;
public class MailSender
{
public static bool SendEmail(
string pGmailEmail,
string pGmailPassword,
string pTo,
string pSubject,
string pBody,
System.Web.Mail.MailFormat pFormat,
string pAttachmentPath)
{
try
{
System.Web.Mail.MailMessage myMail = new System.Web.Mail.MailMessage();
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpserver",
"smtp.gmail.com");
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpserverport",
"465");
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendusing",
"2");
//sendusing: cdoSendUsingPort, value 2, for sending the message using
//the network.
//smtpauthenticate: Specifies the mechanism used when authenticating
//to an SMTP
//service over the network. Possible values are:
//- cdoAnonymous, value 0. Do not authenticate.
//- cdoBasic, value 1. Use basic clear-text authentication.
//When using this option you have to provide the user name and password
//through the sendusername and sendpassword fields.
//- cdoNTLM, value 2. The current process security context is used to
// authenticate with the service.
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate","1");
//Use 0 for anonymous
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendusername",
pGmailEmail);
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendpassword",
pGmailPassword);
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpusessl",
"true");
myMail.From = pGmailEmail;
myMail.To = pTo;
myMail.Subject = pSubject;
myMail.BodyFormat = pFormat;
myMail.Body = pBody;
if (pAttachmentPath.Trim() != "")
{
MailAttachment MyAttachment =
new MailAttachment(pAttachmentPath);
myMail.Attachments.Add(MyAttachment);
myMail.Priority = System.Web.Mail.MailPriority.High;
}
System.Web.Mail.SmtpMail.SmtpServer = "smtp.gmail.com:465";
System.Web.Mail.SmtpMail.Send(myMail);
return true;
}
catch (Exception ex)
{
throw;
}
}
}

How to use Microsoft.Exchange.WebServices?

i try to use : Microsoft.Exchange.WebServices.dll to use outlook. but connection return error
Error return line:service.AutodiscoverUrl("myusernamek#xxxx.com");
The Autodiscover service could not be located. my codes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Exchange.WebServices.Autodiscover;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace test
{
class Program
{
static void Main(string[] args)
{
try
{
// Connect to Exchange Web Services as user1 at contoso.com.
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new WebCredentials("myusernamek#xxxx.com", "mypassword", "xxxx.com");
service.TraceEnabled = true;
service.AutodiscoverUrl("myusernamek#xxxx.com");
// Create the e-mail message, set its properties, and send it to user2#contoso.com, saving a copy to the Sent Items folder.
EmailMessage message = new EmailMessage(service);
message.Subject = "Interesting";
message.Body = "The proposition has been considered.";
message.ToRecipients.Add("recipientname#xxxx.aero");
message.SendAndSaveCopy();
// Write confirmation message to console window.
Console.WriteLine("Message sent!");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
Console.ReadLine();
}
}
}
}
I know this is an old question, but recently wrestled with this and similar looking error (including ISA server). It was fixed with:
service.EnableScpLookup = false;
This was not required when working with an explicit URL, but was when using AutoDiscover
This is a common problem , Autodiscover service error is encountered when this autodiscover service by exchange is down
Resolution is to provide actual URL for exchange location , rather than autodiscovering it.
This solved my same issue.
The code suggest that you have an Exchange 2007 server... Is it properly configured for using the Autodiscover features? Confirm that you can ping autodiscover.XXXX.com and view https://autodiscover.XXXX.com in a web browser.
Alternately, you may need to use your internal domain name for autodiscovery and login. For example, in my office the external email addresses are on a domain like CompanyX.com, but the internal Active Directory domain is like CompanyX.local, and we do not have autodiscover on the open Internet, so my EWS needs to locate Autodiscover.CompanyX.local.
this is an old post but maybe someone will need it.
do not use auto discover, it is rly slow.
how to find your exchange url:
-open your outlook application and connect to your exchange
-hold Ctrl key and right click on the outlook icon in the system tray
-select "test e-mail auto configuration"
-click the test button
-look for the following line:
oh and to use the url you trop that extra line of code:
service.Url = new Uri("your url here");
try these concept:
private static ExchangeService getService(String userEmail, String login, String password, String hostName)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
AutodiscoverService auservice = new AutodiscoverService(hostName);
if (auservice.ServerInfo != null)
{
try
{
service.AutodiscoverUrl(userEmail, RedirectionUrlValidationCallback);
}
catch (AutodiscoverRemoteException ex)
{
Console.WriteLine("Exception thrown: " + ex.Error.Message);
}
}
else
{
service.Url = new Uri("https://" + hostName + "/EWS/Exchange.asmx");
}
service.UseDefaultCredentials = true;
if (service.ServerInfo == null)
{
service.Credentials = new WebCredentials(login, password);
}
return service;
}

Categories

Resources