3

Am using EWS in order to access to the inbox of an email account. But I keep getting this error:

The request failed. The remote server returned an error: (401) Unauthorized.

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = new WebCredentials("account@company.net","password","domain");
service.Url = new Uri("https://webpage.net/EWS/exchange.asmx");
//SearchFilter searchFilter = new  SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true));
ItemView view = new ItemView(10);
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox,view);//i get the error in this line of code

foreach (Item item in findResults.Items)
{
    Console.WriteLine(item.Subject);
}
Jacob
  • 77,566
  • 24
  • 149
  • 228
rdk1992
  • 406
  • 1
  • 5
  • 20
  • You need to provide more context. As is, the fact that the server says you're unauthorized means just that. Are the credentials correct? – Jacob Feb 16 '12 at 16:44
  • they have to be, i access outlook inbox with the same credentials i put on those fields, thats the part thats flippin me out – rdk1992 Feb 16 '12 at 16:48
  • The problem may be in the URL, then. Perhaps the service endpoint is misconfigured or the URL is wrong. – Jacob Feb 16 '12 at 17:17
  • i put the url in the browser the website asks for authentication, i use the same user and pw i put in the fields of webcredentials and i get a bunch of xml. Does that means that at least the url and credentials are alright? – rdk1992 Feb 16 '12 at 17:22
  • 1
    OK, good to know that you tried the basics. Maybe the `@company.net` is unnecessary. – Jacob Feb 16 '12 at 17:28
  • we use owa btw, i know that url is wrong but dont know whats missing and the autodiscovery is disable in the server and admins dont want to put it on >.> – rdk1992 Feb 16 '12 at 17:39
  • possible duplicate of [Exchange Web Service API and 401 unauthorized exception](http://stackoverflow.com/questions/13517323/exchange-web-service-api-and-401-unauthorized-exception) – Shadow The GPT Wizard May 25 '14 at 08:07

4 Answers4

4

The @company.net is breaking it.

Jeff
  • 41
  • 2
0

If your password has expired, you'll get this error.

I had to log in using the user's account directly and set the new password to get it working again.

Gavin Ward
  • 1,022
  • 8
  • 12
0

I know this is from forever ago, but I just ran into this same issue. Come to find out, (at least for our company) it is because I needed to create an app password in office 365. Our IT added 2 step authentication.

Instructions here: https://support.office.com/en-us/article/Create-an-app-password-for-Office-365-3e7c860f-bda4-4441-a618-b53953ee1183

bird2920
  • 373
  • 2
  • 9
-1

I'll let you have a piece of code I made that is working. I also had the 401 Auth issue, that was while back and I don't remember what I exactly modified to make it work, but it does now. Of course you don't need the whole code but it gives you an idea.

public class Outlook
{
    /// <summary>
    /// Returns the selected node Index which equals selected mail index.
    /// </summary>
    public static Int32 selectedMailindex
    {
        get
        {
            return (Int32)Form1.GlobalAccess.Invoke((Func<int>)delegate
            {
                return Form1.GlobalAccess.mailTree.SelectedNode.Index;
            }); 
        }
    }

    static PullSubscription subscriptionInbox;
    public static ExchangeService runningService;

    /// <summary>
    /// Used to save EmailMessage retrieved from user inbox.
    /// </summary>
    public static List<EmailMessage> mailMessages = new List<EmailMessage>();

    /// <summary>
    /// We start the procedure to grab Emails.
    /// </summary>
    public static void StartupLoadMails()
    {
        ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
        service.TraceEnabled = true;
        service.Credentials = new WebCredentials("username", "password"); //Modify this
        service.Url = new Uri("Exchange.asmx URL"); //Modify this
        GetBinding(service);
        runningService = service;
        GetMailItems(runningService);
    }

    static ExchangeService GetBinding(ExchangeService service)
    {
        //Subscribe to Inbox newmail/modified events.
        subscriptionInbox = service.SubscribeToPullNotifications(
        new FolderId[] { WellKnownFolderName.Inbox }, //Inbox
        5, //TimeOut
        null,
        EventType.NewMail, EventType.Modified); //NewMail or Modified
        // Display the service URL.
        return service;
    }

    /*static bool RedirectionUrlValidationCallback(String redirectionUrl)
    {
        return true;
    }*/

    public static void GetMailItems(ExchangeService service)
    {
        Form1.GlobalAccess.Invoke(new Action(() =>
        {
            Form1.GlobalAccess.mailTree.Nodes.Clear();                
        }));
        mailMessages.Clear();
        //SearchFilter to get unreaded messages only.
        SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
        //Create new Item view with the last 9 unreaded items.
        ItemView view = new ItemView(9);
        //Execute the query
        FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, sf, view);
        //We use Parallel for faster initial app loading, reducing ~5/10 secs.
        Parallel.ForEach(findResults, item =>
            {
                try
                {
                    EmailMessage message = EmailMessage.Bind(service, item.Id);
                    mailMessages.Add(message);
                }
                catch
                {
                    MessageBox.Show("ERROR");
                }
            });

        //Since we used parallel we need to sort the emails in our EmailMessage LIST by date, so they show cronologicaly over the treeview.
        mailMessages.Sort(delegate(EmailMessage m1, EmailMessage m2) { return m2.DateTimeReceived.Date.CompareTo(m1.DateTimeReceived.Date); });
        foreach (EmailMessage m in mailMessages)
        {
            Form1.GlobalAccess.Invoke(new Action(() =>
            {
                Form1.GlobalAccess.mailTree.Nodes.Add(m.Subject + " : " + m.Sender.Name);
            }));
        }
    }

    /// <summary>
    /// Calls threaded MarkReaded function to mark an Email as readed localy and remotly.
    /// </summary>
    public static void MarkReaded()
    {
        Thread thread = new Thread(CallThreadedReadFunction);
        thread.Priority = ThreadPriority.AboveNormal;
        thread.Start();
    }

    static void CallThreadedReadFunction()
    {
        ReadFunction(Outlook.mailMessages[selectedMailindex],selectedMailindex,runningService);
    }

    /// <summary>
    /// Mark as readed
    /// </summary>
    /// <param name="message">E-mail Message</param>
    /// <param name="index">Index Message Possition</param>
    /// <param name="service">EWS Service</param>
    static void ReadFunction(EmailMessage message, Int32 index, ExchangeService service)
    {
        Form1.GlobalAccess.Invoke(new Action(() =>
        {
            Form1.GlobalAccess.mailTree.Nodes[index].SelectedImageIndex = 3;
            Form1.GlobalAccess.mailTree.Nodes[index].ImageIndex = 3;
        }));
        EmailMessage msg = EmailMessage.Bind(service, message.Id);
        msg.IsRead = true;
        msg.Update(ConflictResolutionMode.AutoResolve);
    }

    /// <summary>
    /// Calls threaded Delete function to delete an Email localy and remotly.
    /// </summary>
    public static void Delete()
    {
        var deleteWorker = new BackgroundWorker();

        deleteWorker.DoWork += (sender, args) =>
        {
            DeleteFunction(Outlook.mailMessages[selectedMailindex], selectedMailindex, runningService);
        };

        deleteWorker.RunWorkerCompleted += (sender, args) =>
        {
            if (args.Error != null)
                MessageBox.Show(args.Error.ToString());

            Form1.GlobalAccess.Invoke(new Action(() =>
            {
                Form1.GlobalAccess.mailrefreshIcon.Visible = true;
            }));
        };

        deleteWorker.RunWorkerAsync();
    }

    /// <summary>
    /// Delete Emails choosen by the user.
    /// </summary>
    /// <param name="message">E-mail Message</param>
    /// <param name="index">Index Message Possition</param>
    /// <param name="service">EWS Service</param>
    public static void DeleteFunction(EmailMessage message, Int32 index, ExchangeService service)
    {
        try
        {
            Form1.GlobalAccess.Invoke(new Action(() =>
            {
                Form1.GlobalAccess.mailTree.Nodes.RemoveAt(index);
                mailMessages.RemoveAt(index);
                Form1.GlobalAccess.mailTree.SelectedNode = null;
                Form1.GlobalAccess.mailBrowser.DocumentText = null;
            }));

            EmailMessage msg = EmailMessage.Bind(service, message.Id);
            msg.Delete(DeleteMode.MoveToDeletedItems);
            msg.Update(ConflictResolutionMode.AlwaysOverwrite);
        }
        catch
        {
            //En ocaciones, si se borran muchos emails consecutivamente y se da refresh al inbox rapidamente, causa un crash porque el servidor encuentra el email que ordenamos borrar y mientras esta
            //Iterando es borrado, causando un crash. Lo mejor es unicamente ignorar la excepción, el programa seguira trabajando bien.
        }
    }

    /// <summary>
    /// Listens for new mails in the user inbox folder, if found, notifies the user and update mail list.
    /// </summary>
    /// <param name="service">EWS Service</param>
    public static void GetLatests(ExchangeService service)
    {
        GetEventsResults eventsInbox = subscriptionInbox.GetEvents();
        EmailMessage message;
        // Loop through all item-related events.
        foreach (ItemEvent itemEvent in eventsInbox.ItemEvents)
        {
            switch (itemEvent.EventType)
            {
                case EventType.NewMail:
                    try
                    {
                        Item item = Item.Bind(service, itemEvent.ItemId);
                        if (item.ItemClass.ToLower() == "IPM.Note".ToLower())
                        {
                            message = EmailMessage.Bind(service, itemEvent.ItemId);
                                Form1.GlobalAccess.Invoke(new Action(() =>
                                {
                                if (Form1.GlobalAccess.mailTree.Nodes.Count == 8)
                                {
                                    try
                                    {
                                        Form1.GlobalAccess.mailTree.Nodes.RemoveAt(8);
                                        mailMessages.RemoveAt(8);
                                    }
                                    catch
                                    {
                                    }
                                }
                                Form1.GlobalAccess.mailTree.Nodes.Insert(0, message.Subject);
                                mailMessages.Insert(0, message);
                                }));
                            }               
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    break;
            }
        }
    }

    /// <summary>
    /// Reply to a single user. This method gets called from ReplyMail winform.
    /// </summary>
    /// <param name="message">Email Message OBJECT</param>
    /// <param name="index">Email position in the tree</param>
    /// <param name="service">EWS Current Service</param>
    /// <param name="bodyText">Message Text</param>
    /// <param name="subject">Message Original Subject</param>
    public static void Reply(EmailMessage message, Int32 index, ExchangeService service, String bodyText, String subject)
    {
        var replyWorker = new BackgroundWorker();

        replyWorker.DoWork += (sender, args) =>
        {
            bool replyToAll = false;
            ResponseMessage responseMessage = message.CreateReply(replyToAll);
            responseMessage.BodyPrefix = bodyText;
            responseMessage.Subject = subject;
            responseMessage.SendAndSaveCopy();
        };

        replyWorker.RunWorkerCompleted += (sender, args) =>
        {
            if (args.Error != null)
                MessageBox.Show(args.Error.ToString());

            ReplyMail.GlobalAccess.Invoke(new Action(() =>
            {
                ReplyMail.GlobalAccess.mailSentPic.Visible = true;
                ReplyMail.GlobalAccess.MailSentTxt.Visible = true;
                ReplyMail.GlobalAccess.button2.Visible = true;
            }));
        };
        replyWorker.RunWorkerAsync();

    }

    /// <summary>
    /// Forward an E-mail, lets you introduce recipients.
    /// </summary>
    /// <param name="message">EMAILMESSAGE</param>
    /// <param name="index">Mail position on the treeview</param>
    /// <param name="service">EWS Service</param>
    /// <param name="addresses">List with the mail adresses that the user is forwarding to</param>
    public static void Forward(EmailMessage message, Int32 index, ExchangeService service, List<EmailAddress> addresses)
    {
        var forwardWorker = new BackgroundWorker();

        forwardWorker.DoWork += (sender, args) =>
        {
            message.Forward(message.Body.Text, addresses);
        };

        forwardWorker.RunWorkerCompleted += (sender, args) =>
        {
            if (args.Error != null)
                MessageBox.Show(args.Error.ToString());

            ReplyMail.GlobalAccess.Invoke(new Action(() =>
            {
                ReplyMail.GlobalAccess.mailSentPic.Visible = true;
                ReplyMail.GlobalAccess.MailSentTxt.Visible = true;
                ReplyMail.GlobalAccess.button2.Visible = true;
            }));
        };
        forwardWorker.RunWorkerAsync();            
    }

    /// <summary>
    /// Send a single E-Mail
    /// </summary>
    /// <param name="service">EWS Service</param>
    /// <param name="subject">EMAILMESSAGE subject</param>
    /// <param name="bodyText">EMAILMESSAGE body.text</param>
    /// <param name="destination">EMAILADDRESS from receiver</param>
    public static void Send(ExchangeService service, String subject, String bodyText, String destination)
    {
        var sendWorker = new BackgroundWorker();

        sendWorker.DoWork += (sender, args) =>
        {
            EmailMessage message = new EmailMessage(service);
            message.Subject = subject;
            message.Body = bodyText;
            message.ToRecipients.Add(destination);
            message.SendAndSaveCopy();
        };

        sendWorker.RunWorkerCompleted += (sender, args) =>
        {
            if (args.Error != null)
                MessageBox.Show(args.Error.ToString());

            ReplyMail.GlobalAccess.Invoke(new Action(() =>
            {
                ReplyMail.GlobalAccess.mailSentPic.Visible = true;
                ReplyMail.GlobalAccess.MailSentTxt.Visible = true;
                ReplyMail.GlobalAccess.button2.Visible = true;
            }));
        };
        sendWorker.RunWorkerAsync();           
    }
}

}

Scott
  • 21,211
  • 8
  • 65
  • 72
  • 5
    It's good that you have shared your code, but you have provided rather a large haystack, and a hint that there may or may not be the correct answer (needle) in there. It would be better if you could determine the difference between your solution and the OP's then suggest those changes. But kudos for trying to help and the well formatted answer. – Scott Sep 19 '12 at 07:45