EWS exception : "Connection failed. Try later." - c#

Every time I try to call the server, I get an error code : ErrorConnectionFailed with Connection failed. Try later. message.
I suspect that it comes from the fact that the credentials of service are empty. Although I have no idea why. If I create the credentials manually using my windows account login and password, it works fine : new WebCredentials(login, password, domain);
I have a console program that works fine (see below), but it does not on a web site.
static void Main(string[] args)
{
var service = GetContextualService(email);
EmailMessage email = EmailMessage.Bind(service, new ItemId(validEmailId));
Console.ReadKey();
}
private static ExchangeService GetContextualService(string email)
{
ExchangeService service = new ExchangeService();
// I don't even need credentials on a Console program to make it work
//service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);
//service.UseDefaultCredentials = true;
service.AutodiscoverUrl(email, RedirectionUrlValidationCallback);
return service;
}
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;
}
While using on a website even with new WebCredentials(CredentialCache.DefaultCredentials);, it returns an exception. (see below)
private ExchangeService GetContextualService(string email)
{
ExchangeService service = new ExchangeService();
service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);
//service.UseDefaultCredentials = true;
service.AutodiscoverUrl(email, RedirectionUrlValidationCallback);
return service;
}
[HttpPost]
public List<InternetMessageHeader> GetMailHeader(JObject data)
{
ExchangeService service = GetContextualService(data.GetValue("email").Value<string>());
ItemId id = new ItemId(data.GetValue("mailId").Value<string>());
// EXCEPTION BELOW
EmailMessage email = EmailMessage.Bind(service, id);
return email.InternetMessageHeaders.ToList();
}
Why does any call to EWS returns me an exception ?
Why is it working fine on a console program and not on a web server ?
Any thought is welcome !

Strictly based on the code you posted, all I can say is that when you call AutoDiscoverUrl() it may not be talking to the same server that you need to talk to with EWS. Altho typically AD and EWS are on the CAS, it's possible (I think) to get an EWS URL that points to some other server. I've not been in the code in the EWS Editor in some time, but if it does not call the Managed API, it might do AD slightly differently. I'd suggest calling out the EWS URL before you try the Bind() and seeing if you can paste it into a browser. (It'll redirect you OWA, but the connection will be proven.) I'd also call out the AD URL in the redirection callback so you know who you're talking to. Sorry I can't be of more help.

Related

How to validate Exchange credentials and verify Exchange server communication using EWS managed API?

Using Exchange EWS managed API 2.0, here is a method which I'm using to validate credentials:
public static bool TestExchangeConnetion(UserSettingDTO credential, ServerSettingDTO serverSetting)
{
bool authenticated = false;
Microsoft.Exchange.WebServices.Data.ExchangeService service;
service = new ExchangeService((ExchangeVersion)Enum.Parse(typeof(ExchangeVersion), serverSetting.ExchangeVer));
service.Url = new Uri(serverSetting.ExchangeURL);
service.Credentials = new NetworkCredential(credential.ExchangeUsername, credential.ExchangePassword);
try
{
//make a call to ensure that credentials are working
AlternateIdBase response = service.ConvertId(new AlternateId(IdFormat.EwsId, "Placeholder", credential.ExchangeUsername), IdFormat.EwsId);
}
// The credentials were authenticated. We expect this exception since we are providing intentional bad data for ConvertId
catch (ServiceResponseException)
{
authenticated = true;
}
// The credentials were not authenticated.
catch (ServiceRequestException)
{
authenticated = false;
}
catch (Exception)
{
authenticated = false;
}
return authenticated;
}
This works absolutely fine to validate credentials but I'm looking for a way to differentiate between invalid credentials and Exchange server downtimes. This code returns false for both.
Is it possible to find out if there is an issue communicating to the server (like server downtimes)? The reason for this is I want to notify the user about invalid credentials not server downtimes!
EWS is just a Web-service that runs on IIS (so IIS is looking after authentication) if you just want to check the credentials why don't you just make a Get request against the services.wsdl file or a Get on the Autodiscover endpoint on the CAS server. If the credentails are incorrect that should return a 401 at that point.
Cheers
Glen

Authentication - Only HTTPS scheme is allowed

Currently working on an app that is connecting to Azure Mobile Services, and needs to require a Microsoft Account to authenticate.
I have been following this guide:
http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-windows-universal-dotnet-get-started-users/ Unforunately I have run into this error: Only https scheme is allowed. and I am not entirely sure on how to fix it.
Screenshot of error: http://i.stack.imgur.com/hod9i.png
My code is as follows and comes from the guide listed above.
private async void executiveLoginBtn_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
await AuthenticateAsync();
}
// Define a member variable for storing the signed-in user.
private MobileServiceUser user;
// Define a method that performs the authentication process
// using a Facebook sign-in.
private async System.Threading.Tasks.Task AuthenticateAsync()
{
while (user == null)
{
string message;
try
{
// Change 'MobileService' to the name of your MobileServiceClient instance.
// Sign-in using Facebook authentication.
user = await App.MobileService
.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);
message =
string.Format("You are now signed in - {0}", user.UserId);
}
catch (InvalidOperationException)
{
message = "You must log in. Login Required";
}
var dialog = new MessageDialog(message);
dialog.Commands.Add(new UICommand("OK"));
await dialog.ShowAsync();
}
}
The error also says "WinRT Information: URI Scheme is not https" - so how could I go about making the URI scheme https or otherwise fixing this error when authenticating to Azure Mobile Services?
1) Select the local MobileService project in Solution Explorer.
2) In the Properties window, change SSL Enabled to True.
3) Take note of the SSL URL and use that address to initialize the MobileServiceClient object in your client application.
How I fix the error is as follows:
SSL Enabled to True.
http://azure.microsoft.com/en-us/documentation/articles/mobile-services-how-to-register-microsoft-authentication/
Input to Redirect URL
App.xaml.cs
public static MobileServiceClient MobileService = new MobileServiceClient("http://service.azure-mobile.net/", "---------------------");
Change to
public static MobileServiceClient MobileService = new MobileServiceClient("https://service.azure-mobile.net/", "---------------------");

Windows Service C#: Accessing Mail. The Autodiscover service couldn't be located

I have tried both the methods below but both return the result "The Autodiscover service couldn't be located."
http://msdn.microsoft.com/en-us/library/gg591267(v=EXCHG.140).aspx
service.Credentials = new NetworkCredential(userData.EmailAddress, userData.Password);
if (userData.AutodiscoverUrl == null)
{
service.AutodiscoverUrl(userData.EmailAddress, RedirectionUrlValidationCallback);
userData.AutodiscoverUrl = service.Url;
}
else
{
service.Url = userData.AutodiscoverUrl;
}
return service;
}
http://code.msdn.microsoft.com/Exchange-2013-Set-pull-14c8360b#content
static ExchangeService GetBinding()
{
// Create the binding.
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
// Define credentials.
service.Credentials = new WebCredentials("myemail#work.com", "password");
// Use the AutodiscoverUrl method to locate the service endpoint.
try
{
service.AutodiscoverUrl("myemail#work.com", RedirectionUrlValidationCallback);
}
catch (AutodiscoverRemoteException ex)
{
Console.WriteLine("Exception thrown: " + ex.Error.Message);
}
// Display the service URL.
Console.WriteLine("AutodiscoverURL: " + service.Url);
return service;
}
In the one instance I enter my email and password, in the other its hard-coded. Both hang when attempting Autodiscoverurl and eventually fail with the message "The Autodiscover service couldn't be located." I added the references as per the tutorials and Autodiscover appears under Microsoft.Exchange.WebServices.dll ... Is there something else I'm missing?
try adding:
service.UseDefaultCredentials = false;
after you set the credentials
I don't know if you have resolved it yet, I bumped into your post as I was searching for a solution for the same (or similar?) problem.
The peculiar thing was:
Since it worked perfectly in Debug mode, but not once installed as Windows service, I changed the 'Log On' settings in the Windows Service Properties (services.msc, right click on installed service, Properties, Log On Tab) and set it to 'Local System account' and checked the 'Allow service to interact with desktop' option.
That did the trick for me.

Check exchange credentials remotely and check user logged in

I have attempted this with not much success. Basically I need to login to Exchange using EWS remotely.
The issue is I don't know if the user has logged in OK or if the credentials are wrong as I get nothing back! If I provide wrong credentials the software just carries on!
Is there something I'm missing, I've checked the MSDN stuff about EWS which shows you how to connect to exchange but nothing about validating credentials!
Below is the code I currently have to connect.
public void connect(string Email, string Password)
{
try
{
_useremail = Email;
_userpass = Password;
// Define the credentials to use.
var credentials = new WebCredentials(_useremail, _userpass);
_ExchangeServer = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
_ExchangeServer.Credentials = credentials;
_ExchangeServer.Url = new Uri(_ExchangeEWSURL);
_ExchangeServer.Timeout = 60;
_ExchangeServer.KeepAlive = true;
_ExchangeConnected = true;
}
catch (Exception ex)
{
_ExchangeConnected = false;
throw ex;
}
}
as you can see at present I just set a bool value to true in the class. Any ideas?
In order to check whether the given credentials are valid, you must query resources you expect the user to have access to (calendar, inbox, contacts, etc.). There is no explicit login method - the authentication occurs implicitly when you request user resources (via FindItems, FindFolders, FindAppointments, etc.).

Confirm service credentials changed

I am using the following code to change the credentials of a windows service. Before I display the message that credentials were successfully changed, I want to confirm the new credentials have been applied. How can I do that?
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{
object[] wmiParams = new object[11];
wmiParams[6] = _username;
wmiParams[7] = _password;
service.InvokeMethod("Change", wmiParams);
Thread.Sleep(2000);
//check if new credentials in order
//Console.WriteLine("Service credentials changed");
}
The new credentials won't apply until you restart the service, and I suggest you use the ServiceController instead of WMI.
You should be able to check the returned object from InvokeMethod and just handle errors without any further complexity. The only issue is working out what returned value implies success.
object result = service.InvokeMethod("Change", wmiParams);
// if result 'is bad', handle error

Categories