Search code examples
c#exchangewebservicesews-managed-apiexchange-server-2013

EWS managed API SearchMailboxes generates exception on production server with ServiceXmlDeserializationException


I'm having a serious issue with EWS managed API and though I published an issue on github for this project, I didn't received any feedback and this is why I really hope that here is someone who can point me in the right direction (last week I had another issue with EWS and thanks to this wonderful community, that issue had been solved).

Now about my issue: as I already told you, I'm using EWS managed API to find some messages using a simple query. On a test environment with only few items / mailbox, the search is working perfectly but when I put it in production I'm getting quite a strange issue (exception):

[ServiceXmlDeserializationException: An element node 't:Mailbox' of the type Element was expected, but node 't:SearchScope' of type Element was found.]
   Microsoft.Exchange.WebServices.Data.EwsXmlReader.InternalReadElement(XmlNamespace xmlNamespace, String localName, XmlNodeType nodeType) +451
   Microsoft.Exchange.WebServices.Data.SearchMailboxesResult.LoadFromXml(EwsServiceXmlReader reader) +464
   Microsoft.Exchange.WebServices.Data.SearchMailboxesResponse.ReadElementsFromXml(EwsServiceXmlReader reader) +47
   Microsoft.Exchange.WebServices.Data.ServiceResponse.LoadFromXml(EwsServiceXmlReader reader, String xmlElementName) +360
   Microsoft.Exchange.WebServices.Data.SearchMailboxesRequest.ParseResponse(EwsServiceXmlReader reader) +230
   Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ReadResponse(EwsServiceXmlReader ewsXmlReader) +157
   Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.ReadResponseXml(Stream responseStream) +87
   Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.ReadResponse(IEwsHttpWebResponse response) +403
   Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute() +53
   XXX.XXX.MailManager.Admin.Controllers.MailingManagerController.Search(MailingManagerMasterModel masterModel) +722
   lambda_method(Closure , ControllerBase , Object[] ) +139
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +209
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +35
   System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +72
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +30
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +186
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137

The code for doing the search is the following:

List<MailboxSearchScope> mailboxSearchScopes = new List<MailboxSearchScope>();
                foreach (SearchableMailbox mailbox in response.SearchableMailboxes)
                {
                    mailboxSearchScopes.Add(new MailboxSearchScope(mailbox.ReferenceId, MailboxSearchLocation.All));
                }

                SearchMailboxesParameters searchMailboxesParameters = new SearchMailboxesParameters();

                List<MailboxQuery> queries = new List<MailboxQuery>()
                    {
                        new MailboxQuery(String.Format("Body:{0} OR Subject:{0}", masterModel.FilteringOptions.Subject), mailboxSearchScopes.ToArray())
                    };

                searchMailboxesParameters.SearchQueries = queries.ToArray();
                searchMailboxesParameters.PerformDeduplication = false;
                searchMailboxesParameters.ResultType = SearchResultType.PreviewOnly;

                ServiceResponseCollection<SearchMailboxesResponse> responseCollection = service.SearchMailboxes(searchMailboxesParameters);

Where do you think is the issue?

Thank you very much for your help.


Solution

  • So, thanks to the suggestion given by Glen, I was able to fix the issue - I enabled tracing and I logged all the requests and responses to an xml file and this way I found the bug.

    Long story short - somehow (don't ask why because I have no idea) during the enumeration of the searchable mailboxes to be put as MailboxSearchScope, I discovered that some of them had the ReferenceId an empty string and from here, the generated request was invalid.

    So, what I did was pretty simple:

    foreach (SearchableMailbox mailbox in response.SearchableMailboxes)
                    {
                        if (String.IsNullOrEmpty(mailbox.ReferenceId))
                            continue;
    
                        mailboxSearchScopes.Add(new MailboxSearchScope(mailbox.ReferenceId, MailboxSearchLocation.All));
                    }