none
Connect to Exchange Online (Using API) with SharePoint 2010 RRS feed

  • Question

  • Hi All!

    I have a UserControl that count's the User Messages, it works outside SharePoint and in Sharepoint 2007, but in Version 2010 i can't make it to work, it give me always that the Autodiscovery Service could not be located, bellow is my Service Binding Method

    using Microsoft.Exchange.WebServices.Autodiscover;
    using Microsoft.Exchange.WebServices.Data;
    
    public static ExchangeService GetBinding()
    {
      try
      {
        //Create Service
        ExchangeService service = new
          ExchangeService(ExchangeVersion.Exchange2010_SP1);
        //Assign Credentials
        service.Credentials = new
          WebCredentials("admin@contoso.com", "password");
        // Create an instance of the AutodiscoverService.
        AutodiscoverService ads = new
          Autodiscover.AutodiscoverService();
        // Enable tracing.
        ads.TraceEnabled = true;
        // Set the credentials.
        ads.Credentials = service.Credentials;
        // Prevent the AutodiscoverService from 
        //looking in the local Active Directory
        // for the Exchange Web Services Services SCP.
        ads.EnableScpLookup = false;
        // Specify a redirection URL validation 
        //callback that returns true for valid URLs.
        ads.RedirectionUrlValidationCallback =
          RedirectionUrlValidationCallback;
        // Get the Exchange Web Services URL for the user's mailbox.
        GetUserSettingsResponse response =
          ads.GetUserSettings("admin@contoso.com",
            UserSettingName.ExternalEwsUrl);
        // Extract the Exchange Web Services URL from the response.
        var externalEwsUrl = new
        Uri(response.Settings[UserSettingName.ExternalEwsUrl].ToString());
        // Set the URL of the ExchangeService object.
        service.Url = externalEwsUrl;
        return service;
      }
      catch (AutodiscoverRemoteException ex)
      {
        Console.WriteLine("Exception thrown: " + ex.Error.Message);
        return null;
      }
    }
    
    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;
    }
    

    I have the same proxy configurations and it works in a Console Application in the same Server.

    I hope someone can give me some help on this.

    Thanks

    Joao

     


    MVP Office Development, MCP, MCTS SharePoint 2010 Development
    Wednesday, July 27, 2011 11:55 AM

All replies

  • Hi Joao,

    do you see anything in the trace output?

    Kind regards,
    Henning

    Wednesday, July 27, 2011 12:17 PM
  • Hi!

    In my console application i can see all trace output plus my messages count

     

     static void Main(string[] args)
      {
       try
       {
        ItemView view = new ItemView(100, 0);
        SearchFilter sf = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true);
        FindItemsResults<Item> findResults = GetBinding().FindItems(WellKnownFolderName.Inbox, sf, view);
        Console.WriteLine("Inbox Not Read: " + findResults.Items.Count);
        Console.Read();
       }
       catch (Exception exception)
       {
        Console.WriteLine(exception.ToString());
        Console.ReadLine();
       }
    
      }
    

     Click: http://exchws.files.wordpress.com/2011/07/output.jpg


    MVP Office Development, MCP, MCTS SharePoint 2010 Development

    Wednesday, July 27, 2011 12:30 PM
  • A trace output from the SharePoint Lookup would be great.

    Use this:
    internal class CustomTraceListener : ITraceListener {
           private readonly TextWriter _Writer;
            public CustomTraceListener(TextWriter writer)
           {
               _Writer = writer;
           }
            public void Trace(string traceType, string traceMessage)
           {
               _Writer.WriteLine("{0}, {1}:", DateTime.Now, traceType);
               _Writer.WriteLine(traceMessage);
               _Writer.WriteLine(new string('=', 80));
           }
       }

    When you create your ExchangeService instance, add this:
    var writer = new StringWriter();
    service.TraceListener = new CustomTraceListener(writer);

    you can access the log afterwards with:
    writer.Flush();
    var log = writer.ToString();

    Kind regards,
    Henning

    Wednesday, July 27, 2011 12:52 PM
  • Hi Henning!

    When i invoke the CustomTraceListner Class, i could't get my trace, but it give me a clue, in the bellow line, instead i get a AutodiscoverRemoteException i have AutodiscoverLocalException  

    GetUserSettingsResponse response =
       ads.GetUserSettings("admin@contoso.com",
        UserSettingName.ExternalEwsUrl);
    
    

    Let me explain in more detail my Infrastructure. The domain contoso.com is primerly hosted in my corporation, but whe have all DNS Hosts in order to resolve the autodiscovery, something like this

    CNAME
    
    Type: MX
    Host: yourhost.com
    MX Server: 99999999.mail.outlook.com
    TTL: 3.600 or 1 hour
    Priority: 0

    In the other hand, i can resolve the autodiscovery service simply using this in my Console Application

    string _userSMTPAddress = "danj@contoso.com";
    string _password = "myP@ssword";
    
    var credentials = new WebCredentials()
    {
      UserName = _userSMTPAddress,
      Password = _password
    };
    
    _exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
    _exchangeService.Credentials = credentials;
    _exchangeService.AutodiscoverUrl(_userSMTPAddress, RedirectionUrlValidationCallback);
    

    But let me post here my method that works in MOSS but not in SharePoint 2010

    /// <summary>
        /// Gets the binding.
        /// </summary>
        /// <returns></returns>
        public static ExchangeService GetBinding()
        {
          // Create the binding.
          ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
          //Proxy
          IWebProxy proxy = new WebProxy(GetUrl.ProxyAddress, true)
                     {
                       Credentials = new NetworkCredential(GetUrl.ProxyUser, GetUrl.ProxyPass,
                         GetUrl.ProxyDomain)
                     };
    
          WebRequest.DefaultWebProxy = proxy;
          service.Credentials = new WebCredentials("admin@contoso.com", "password");
    
          try
          {
            // Use the AutodiscoverUrl method to locate the service endpoint.
            service.AutodiscoverUrl("admin@contoso.com", RedirectionUrlValidationCallback);
          }
          catch (AutodiscoverRemoteException ex)
          {
            Console.WriteLine("Exception thrown: " + ex.Error.Message);
          }
          return service;
        }
    
        static bool RedirectionUrlValidationCallback(String redirectionUrl)
        {
          // Perform validation.
          // Validation is developer dependent to ensure a safe redirect.
          return true;
        }

    Simply none of MY approaches work in SHAREPOINT 2010

     


    MVP Office Development, MCP, MCTS SharePoint 2010 Development
    Wednesday, July 27, 2011 1:49 PM
  • Hi!
    I could make it work simply invoking the service URL as fixed and use the RemoteCertificateValidationHandler because of "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel" Error.
    Thanks for helping Henning ;)
     /// <summary>
        /// Gets the binding.
        /// </summary>
        /// <returns></returns>
        public static ExchangeService GetBinding()
        {
          try
          {
            //Create Service
            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
            //Assign Credentials
            service.Credentials = new WebCredentials("admin@contoso.com", "password");        
            ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidationHandler;
            service.Url = new Uri("https://amsprdXXXX.outlook.com/EWS/Exchange.asmx");
            return service;
          }
          catch (AutodiscoverRemoteException ex)
          {
            Console.WriteLine("Exception thrown: " + ex.Error.Message);
            return null;
          }
        }
    
        
        private static bool RemoteCertificateValidationHandler(object sender, X509Certificate certificate,
          X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
          return true; //ignore the checks and go ahead
        }

    MVP Office Development, MCP, MCTS SharePoint 2010 Development
    Wednesday, July 27, 2011 2:37 PM