【问题标题】:Office365 EWS API The Autodiscover service couldn't be locatedOffice365 EWS API 找不到自动发现服务
【发布时间】:2020-07-13 22:26:12
【问题描述】:

我编写了一个 .Net c# 控制台应用程序,用于从具有特定凭据的 Office365 邮箱中提取电子邮件。 这个应用程序在我的开发 PC 上完美运行。我现在需要将它部署到 Windows 服务器(2019)并通过作业调度程序运行。但是在服务器上它不起作用,我得到“找不到自动发现服务”。错误。 请看我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Exchange.WebServices.Data;
using System.Configuration;
using System.Globalization;
using System.IO;

namespace DWMailProcessor
{
    class Program
    {
        static void Main(string[] args)
        {
            string emailName = ConfigurationManager.AppSettings["emailName"];
            string emailPassWord = ConfigurationManager.AppSettings["emailPassWord"];
            string filterSubject = ConfigurationManager.AppSettings["filterSubject"];
            string extractFilePath = ConfigurationManager.AppSettings["extractFilePath"];
            string emailFolder = ConfigurationManager.AppSettings["emailFolder"];
            string logFilePath = ConfigurationManager.AppSettings["logFilePath"] + $@"\DWMailProcessor.ErrorLog"; ;

            try
            {
                ExchangeService exchange = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
                exchange.Credentials = new WebCredentials(emailName, emailPassWord);
                exchange.AutodiscoverUrl(emailName, RedirectionUrlValidationCallback);

                if (exchange != null)
                {
                    Folder rootFolder = Folder.Bind(exchange, WellKnownFolderName.MsgFolderRoot);
                    SearchFilter ff = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, emailFolder);
                    FindFoldersResults fresult = rootFolder.FindFolders(ff, new FolderView(1));

                    FindItemsResults<Item> result;
                    do
                    {
                        SearchFilter sf = new SearchFilter.IsEqualTo(EmailMessageSchema.Subject, filterSubject);
                        result = exchange.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(100));

                        foreach (Item item in result)
                        {
                            EmailMessage message = EmailMessage.Bind(exchange, item.Id);
                            FileAttachment attachment = (FileAttachment)message.Attachments[0];
                            attachment.Load(extractFilePath + @"\" + attachment.Name);
                            item.Move(fresult.Folders[0].Id);
                        }
                    } while (result.TotalCount > 0);
                }
            }
            catch (Exception e)
            {
                using (StreamWriter sw = new StreamWriter(logFilePath, append: true))
                {
                    sw.WriteLine($"Fatal[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InstalledUICulture)}]: {e.Message}");
                }
                //throw;
                return;
            }
        }

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

注意:所有凭据均从 App.Config 文件中获取 我在服务器上只有有限的权限,我们的 IT 对如何解决这个问题没有太多的线索。 这可能是防火墙问题吗?因为服务器仅限于互联网。即(只有特定的 url 和端口是开放的。IT 说他们打开了https://outlook.office365.com/EWS/Exchange.asmx) 使用 EWS API 需要哪些防火墙规则(如果有)?有没有其他方法可以从服务器解决此问题?

提前非常感谢。

【问题讨论】:

    标签: c# .net office365


    【解决方案1】:

    对于自动发现,它将使用的 URL 是 autodiscover-s.outlook.com。 outlook.office365.com 是 EWS 端点,它基本上是自动发现代码将始终为 Office365 返回的内容,因为这是一个静态端点。如果您使用 Office365,那么您可以认为自动发现是多余的,因为它只会返回 https://outlook.office365.com/EWS/Exchange.asmx,所以我建议您尝试以下方法对 URL 进行硬编码。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Exchange.WebServices.Data;
    using System.Configuration;
    using System.Globalization;
    using System.IO;
    
    namespace DWMailProcessor
    {
        class Program
        {
            static void Main(string[] args)
            {
                string emailName = ConfigurationManager.AppSettings["emailName"];
                string emailPassWord = ConfigurationManager.AppSettings["emailPassWord"];
                string filterSubject = ConfigurationManager.AppSettings["filterSubject"];
                string extractFilePath = ConfigurationManager.AppSettings["extractFilePath"];
                string emailFolder = ConfigurationManager.AppSettings["emailFolder"];
                string logFilePath = ConfigurationManager.AppSettings["logFilePath"] + $@"\DWMailProcessor.ErrorLog"; ;
    
                try
                {
                    ExchangeService exchange = new ExchangeService(ExchangeVersion.Exchange2016);
                    exchange.Credentials = new WebCredentials(emailName, emailPassWord);
                    exchange.Url = new Uri("https://outlook.office365.com/ews/exchange.asmx");
                    exchange.HttpHeaders.Add("X-AnchorMailbox", emailName);
    
                    if (exchange != null)
                    {
                        Folder rootFolder = Folder.Bind(exchange, WellKnownFolderName.MsgFolderRoot);
                        SearchFilter ff = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, emailFolder);
                        FindFoldersResults fresult = rootFolder.FindFolders(ff, new FolderView(1));
    
                        FindItemsResults<Item> result;
                        do
                        {
                            SearchFilter sf = new SearchFilter.IsEqualTo(EmailMessageSchema.Subject, filterSubject);
                            result = exchange.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(100));
    
                            foreach (Item item in result)
                            {
                                EmailMessage message = EmailMessage.Bind(exchange, item.Id);
                                FileAttachment attachment = (FileAttachment)message.Attachments[0];
                                attachment.Load(extractFilePath + @"\" + attachment.Name);
                                item.Move(fresult.Folders[0].Id);
                            }
                        } while (result.TotalCount > 0);
                    }
                }
                catch (Exception e)
                {
                    using (StreamWriter sw = new StreamWriter(logFilePath, append: true))
                    {
                        sw.WriteLine($"Fatal[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InstalledUICulture)}]: {e.Message}");
                    }
                    //throw;
                    return;
                }
            }
    
        }
    }
    

    您的代码的另一个问题是它使用基本身份验证,这将在 10 月进行https://support.microsoft.com/en-au/help/4521831/exchange-online-deprecating-basic-auth,因此请考虑改用 oAuth。

    可能只是查看您使用的代码的最后一件事是,这一切都可以在 Microsoft Graph API(也可能是 PowerAutomate)中完成,这将使您减少应用所需的权限数量,为您提供更大的灵活性您如何/在何处运行它,并为您的工作提供延长寿命的任何流程(如果 EWS 在未来的任何时候关闭)。

    【讨论】:

    • 谢谢格伦,我正在取得一些进展。随着您的更改,我不再收到“无法找到自动发现服务”,但是我收到“请求失败。远程服务器返回错误:(401)未经授权”。凭据是正确的,因为我可以在我的 PC 上连接相同的凭据。当然,该应用程序在服务器上以不同的域帐户运行,该帐户也已添加到邮箱中。在服务器上解决此问题的最佳方法是什么?
    • 尝试使用 fiddler,这将是查看服务器实际发送的凭据的最佳方式。重要的凭证是 exchange.Credentials = new WebCredentials(emailName, emailPassWord);当您在服务器上运行它时,听起来它们无效。 Fiddler 会告诉你任何一种方式,因为你会看到它发送的内容。
    • 感谢您,在 Fiddler 上我可以看到凭据正在正确传递,但是,在 Auth 标签页上它报告“不存在代理身份验证标头”并且仍然给我 (401)未经授权。代理可能有什么问题?
    • 您是否有需要遍历的代理? (提琴手本身就是一个代理)另一种从服务器进行测试的好方法可能是使用 EWSEditor github.com/dseph/EwsEditor/releases,它至少应该允许您测试底层连接。
    猜你喜欢
    • 2016-12-17
    • 2012-09-28
    • 2013-02-10
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    相关资源
    最近更新 更多