我正在尝试通过Mono(版本2.10.8.1和3.0.6)在debian上使用Exchange EWS 2
我正在使用vs2012在Windows 8上进行开发。
该程序在Windows上正常运行,我得到了预期的输出。
但是在单声道上,我不断得到以下输出和异常。
<Trace Tag="AutodiscoverConfiguration" Tid="1" Time="2013-03-07 19:09:05Z">
Starting SCP lookup for domainName='example.com', root path=''
</Trace>
Connect Error
Unhandled Exception: LdapException: (91) Connect Error
System.Net.Sockets.SocketException: No such host is known
at System.Net.Dns.hostent_to_IPHostEntry (System.String h_name, System.String[] h_aliases, System.String[] h_addrlist) [0x00000] in <filename unknown>:0
at System.Net.Dns.GetHostByName (System.String hostName) [0x00000] in <filename unknown>:0
at System.Net.Dns.GetHostEntry (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
at System.Net.Dns.GetHostAddresses (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
at System.Net.Sockets.TcpClient.Connect (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
at System.Net.Sockets.TcpClient..ctor (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
at Novell.Directory.Ldap.Connection.connect (System.String host, Int32 port, Int32 semaphoreId) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: LdapException: (91) Connect Error
System.Net.Sockets.SocketException: No such host is known
at System.Net.Dns.hostent_to_IPHostEntry (System.String h_name, System.String[] h_aliases, System.String[] h_addrlist) [0x00000] in <filename unknown>:0
at System.Net.Dns.GetHostByName (System.String hostName) [0x00000] in <filename unknown>:0
at System.Net.Dns.GetHostEntry (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
at System.Net.Dns.GetHostAddresses (System.String hostNameOrAddress) [0x00000] in <filename unknown>:0
at System.Net.Sockets.TcpClient.Connect (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
at System.Net.Sockets.TcpClient..ctor (System.String hostname, Int32 port) [0x00000] in <filename unknown>:0
at Novell.Directory.Ldap.Connection.connect (System.String host, Int32 port, Int32 semaphoreId) [0x00000] in <filename unknown>:0
显然,它正在尝试查找找不到的主机。
我的Windows和Linux系统都使用同一台dns服务器,因此不是造成此问题的原因。
当工作时,我在Windows上通读了踪迹-踪迹显示查找失败了几次,而autodiscover方法尝试了一些不同的URL,直到碰到了一个可行的URL-在单声道上,但是似乎在第一个之后就掉了。失败,这就是结束。
我已经尝试过在单声道上使用ews进行谷歌搜索,但是我还没有发现有人在使用它,因此我不确定是否还可以尝试其他方法。
下面使用的代码-几乎所有的代码都来自以下代码示例
http://msdn.microsoft.com/en-us/library/exchange/dd633709(v=exchg.80).aspx
class Program
{
private static int verbose = 10;
private static string loginEmail = "email@example.com";
private static string password = "#############";
static void Main(string[] args)
{
try
{
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.Credentials = new WebCredentials(loginEmail, password);
if (verbose >= 10)
{
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
}
service.AutodiscoverUrl(loginEmail, RedirectionUrlValidationCallback);
Console.WriteLine("AutoDiscover Completed");
getContacts(service);
Console.ReadLine();
}
catch (Exception e) {
Console.WriteLine(e.Message);
foreach (string key in e.Data.Keys)
{
Console.WriteLine(String.Format("{0}: {1}",key, e.Data[key]));
}
throw e;
}
}
private static void getContacts(ExchangeService service){
// Get the number of items in the Contacts folder.
ContactsFolder contactsfolder = ContactsFolder.Bind(service, WellKnownFolderName.Contacts);
// Set the number of items to the number of items in the Contacts folder or 1000, whichever is smaller.
int numItems = contactsfolder.TotalCount < 1000 ? contactsfolder.TotalCount : 1000;
// Instantiate the item view with the number of items to retrieve from the Contacts folder.
ItemView view = new ItemView(numItems);
// To keep the request smaller, request only the display name property.
//view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ContactSchema.DisplayName);
// Retrieve the items in the Contacts folder that have the properties that you selected.
FindItemsResults<Item> contactItems = service.FindItems(WellKnownFolderName.Contacts, view);
// Display the list of contacts.
foreach (Item item in contactItems)
{
if (item is Contact)
{
Contact contact = item as Contact;
Console.WriteLine();
Console.WriteLine(contact.DisplayName);
if (verbose >= 2)
{
Console.WriteLine(" " + contact.Id);
}
try
{
Console.WriteLine(" " + contact.EmailAddresses[EmailAddressKey.EmailAddress1].ToString());
}
catch (Exception e)
{
if (verbose >= 5)
{
Console.WriteLine(" " + "Email Address 1 Not Available : " + e.Message);
}
}
}
}
}
#region taken from tutorial
private static bool CertificateValidationCallBack(
object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
if (chain != null && chain.ChainStatus != null)
{
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
{
if ((certificate.Subject == certificate.Issuer) &&
(status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
{
// Self-signed certificates with an untrusted root are valid.
continue;
}
else
{
if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
{
// If there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
return false;
}
}
}
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
return true;
}
else
{
// In all other cases, return false.
return false;
}
}
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;
}
#endregion
}
BeepBeep的回答帮助我解决了这个问题。
在使用BeepBeep的建议之后,我遇到了一个问题,即Mono似乎没有dnsapi.dll(根据异常(exception)情况)。我暂时跳过了自动发现以解决此问题。
为了做到这一点,我更换了
service.AutodiscoverUrl(loginEmail, RedirectionUrlValidationCallback);
和
service.Url = new Uri("https://blah.com/ews/exchange.asmx");
然后我遇到了一个证书错误(该异常说了类似“请求或解密错误”之类的内容)-足以说,您需要知道,默认情况下,mono不包含任何根ca证书,更多信息请参见:Mono FAQ about Security
我使用mozroots工具选择了懒惰的方式来获取我想要的证书。但是,这没有按预期方式工作,并且错误仍然存在。
然后,我也使用上述常见问题解答中的tlstest来确定问题-它与我正在使用的证书链有关(根被接受,但是中间未被接受)。然后,我使用FAQ(certmgr)中记录的第三个工具来安装证书。
之后,一切正常。
最佳答案
同样的问题,并使用此代码解决:
ExchangeService service = new ExchangeService();
service.EnableScpLookup = false;
关于c# - 在Mono LdapException上运行Exchange EWS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15279823/