【问题标题】:The request failed. The remote server returned an error: (401) Unauthorized请求失败。远程服务器返回错误:(401) Unauthorized
【发布时间】:2012-02-16 16:38:59
【问题描述】:

我正在使用 EWS 访问电子邮件帐户的收件箱。但我不断收到此错误:

请求失败。远程服务器返回错误:(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);
}

【问题讨论】:

  • 您需要提供更多上下文。事实上,服务器说您未经授权的事实就是这样。凭据是否正确?
  • 他们必须是,我访问 Outlook 收件箱时使用的凭据与我在这些字段中输入的凭据相同,这就是让我失望的部分
  • 那么问题可能出在 URL 上。可能是服务端点配置错误或 URL 错误。
  • 我将 url 放在网站要求身份验证的浏览器中,我使用相同的用户和密码,我在 webcredentials 字段中输入了一堆 xml。这是否意味着至少 url 和凭据都可以?
  • 好的,很高兴知道您尝试了基础知识。也许@company.net 是不必要的。

标签: c# exchangewebservices


【解决方案1】:

@company.net 正在破坏它。

【讨论】:

    【解决方案2】:

    如果您的密码已过期,您将收到此错误消息。

    我必须直接使用用户帐户登录并设置新密码才能再次使用。

    【讨论】:

      【解决方案3】:

      我知道这是很久以前的事了,但我刚刚遇到了同样的问题。来了解一下,(至少对我们公司而言)是因为我需要在 Office 365 中创建应用密码。我们的 IT 增加了两步验证。

      此处的说明: https://support.office.com/en-us/article/Create-an-app-password-for-Office-365-3e7c860f-bda4-4441-a618-b53953ee1183

      【讨论】:

        【解决方案4】:

        我会让你有一段我编写的有效的代码。我也遇到了401 Auth 问题,那是以前的问题,我不记得我为使其工作而进行的确切修改,但现在可以了。当然你不需要完整的代码,但它会给你一个想法。

        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();           
            }
        }
        

        }

        【讨论】:

        • 很高兴您分享了您的代码,但您提供了相当大的干草堆,并提示其中可能存在或可能没有正确答案(针)。如果您可以确定您的解决方案与 OP 之间的差异,然后建议这些更改,那就更好了。但是,对于尝试提供帮助和格式正确的答案表示敬意。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        • 2020-12-24
        相关资源
        最近更新 更多