EWS Api gives timeout and (503) Server Unavailable - c#

I'm using the following code to get calendar appointments from my Office 365 account with EWS api's set (Microsoft.Exchange.WebServices 2.2.0):
ExchangeService service = new ExchangeService();
service.Credentials = new NetworkCredential(mail, password);
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
Folder DefaultCalendar = Folder.Bind(service, WellKnownFolderName.Calendar);
CalendarView calendarView = new CalendarView(fromDate, toDate);
FindItemsResults<Appointment> resultAppointments = Folder.FindAppointments(calendarView);
often the application crash with the following exceptions:
Microsoft.Exchange.WebServices.Data.ServiceRequestException: The
request failed. The operation has timed out --->
System.Net.WebException: The operation has timed out at
System.Net.HttpWebRequest.GetResponse() at
Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.Microsoft.Exchange.WebServices.Data.IEwsHttpWebRequest.GetResponse()
at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest
request) --- End of inner exception stack trace --- at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest
request) at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest&
request) at
Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
at
Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder(FolderId
folderId, PropertySet propertySet) at
Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder[TFolder](FolderId
folderId, PropertySet propertySet) at
Microsoft.Exchange.WebServices.Data.CalendarFolder.Bind(ExchangeService
service, FolderId id)
or:
Microsoft.Exchange.WebServices.Data.ServiceRequestException: The
request failed. The remote server returned an error: (503) Server
Unavailable. ---> System.Net.WebException: The remote server returned
an error: (503) Server Unavailable. at
System.Net.HttpWebRequest.GetResponse() at
Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.Microsoft.Exchange.WebServices.Data.IEwsHttpWebRequest.GetResponse()
at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest
request) --- End of inner exception stack trace --- at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest
request) at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest&
request) at
Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
at
Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder(FolderId
folderId, PropertySet propertySet) at
Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder[TFolder](FolderId
folderId, PropertySet propertySet) at
Microsoft.Exchange.WebServices.Data.CalendarFolder.Bind(ExchangeService
service, FolderId id)
or:
Microsoft.Exchange.WebServices.Data.ServiceRequestException: The
request failed. The underlying connection was closed: A connection
that was expected to be kept alive was closed by the server. --->
System.Net.WebException: The underlying connection was closed: A
connection that was expected to be kept alive was closed by the
server. at System.Net.HttpWebRequest.GetResponse() at
Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.Microsoft.Exchange.WebServices.Data.IEwsHttpWebRequest.GetResponse()
at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest
request) --- End of inner exception stack trace --- at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest
request) at
Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest&
request) at
Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest1.Execute()
at
Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems[TItem](IEnumerable1
parentFolderIds, SearchFilter searchFilter, String queryString,
ViewBase view, Grouping groupBy, ServiceErrorHandling
errorHandlingMode) at
Microsoft.Exchange.WebServices.Data.Folder.InternalFindItems[TItem](SearchFilter
searchFilter, ViewBase view, Grouping groupBy) at
Microsoft.Exchange.WebServices.Data.CalendarFolder.FindAppointments(CalendarView
view)
or:
The server cannot service this request right now. Try again later.
It seems that sometimes Office 365 services are unreachable or on throttling; I tried to try-catch my code, but the application still crash; I think because a new Thread is opened. How can I handle this issue?

The first place to start is to get the latest version of the EWS Managed API from Github https://github.com/OfficeDev/ews-managed-api . The version you using hasn't been update since 2015 which is when Microsoft stopped releasing compiled versions of that library. However the code has been updated with numerous bug fixes on GitHub
With the code your using I would suggest you always set the X-AnchorMailBox which can cause 503 and timeout issues see
https://blogs.msdn.microsoft.com/webdav_101/2015/05/11/best-practices-ews-authentication-and-access-issues/ (even if your not using Impersonation)
Depending on how much work your application is doing you may get throttled its important in that case to process the exception and retry. Also with Office365 mailboxes get moved around a fair bit on the back-end so it can be common to see period where the Mailbox is inaccessible during these moves
I tried to try-catch my code, but the application still crash; I think because a new Thread is opened. How can I handle this issue?
No it doesn't span a new thread you can check the source yourself on GitHub so you must have another issue with your exception handling.

Related

GRPC - The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR when upgrading from .netcore 3.1 to net5 or net6

I have a .netcore3.1 test project which calls a GRPC service.
The service is only available via HTTP. I cannot change the service now.
When I update the project to .net5-windows or .net6-windows (literally only a csproj change), the calls fail with the following error:
Grpc.Core.RpcException : Status(StatusCode="Unavailable", Detail="Error starting gRPC call. HttpRequestException: An error occurred while sending the request. IOException: The request was aborted. Http2ConnectionException: The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR' (0x1).", DebugException="System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.IO.IOException: The request was aborted.
---> System.Net.Http.Http2ConnectionException: The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR' (0x1).
at System.Net.Http.Http2Connection.ThrowProtocolError(Http2ProtocolErrorCode errorCode)
at System.Net.Http.Http2Connection.ReadFrameAsync(Boolean initialFrame)
at System.Net.Http.Http2Connection.ProcessIncomingFramesAsync()
--- End of inner exception stack trace ---
at System.Net.Http.Http2Connection.ThrowRequestAborted(Exception innerException)
at System.Net.Http.Http2Connection.Http2Stream.CheckResponseBodyState()
at System.Net.Http.Http2Connection.Http2Stream.TryEnsureHeaders()
at System.Net.Http.Http2Connection.Http2Stream.ReadResponseHeadersAsync(CancellationToken cancellationToken)
at System.Net.Http.Http2Connection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.Http2Connection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at Grpc.Net.Client.Web.GrpcWebHandler.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Grpc.Net.Client.Internal.GrpcCall2.RunCall(HttpRequestMessage request, Nullable1 timeout)")
at..
I had a look at few SO questions (e.g. .Net Core 3.1 gRPC client with unencrypted HTTP2 connection and Grpc.Core.RpcException: 'Status (StatusCode = "Unavailable", Detail = "Error starting gRPC call) as well as the 'call insecure service' troubleshooting guide https://learn.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-5.0#call-insecure-grpc-services-with-net-core-client however they are not helpful.
I have tried a few options of setting AppContext (even though they should apply for netcore3.1) like this before initializing a client, but again no help:
AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport”, true);
AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2Support”, true);
The channel is initialized as follows:
var baseUri = new Uri(baseUrl);
HttpMessageHandler httpMessageHandler = new HttpClientHandler();
if (baseUri.AbsolutePath != "/")
httpMessageHandler = new SubDirectoryHandler(httpMessageHandler, baseUri.AbsolutePath);
var handler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, httpMessageHandler);
_channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions { HttpClient = new HttpClient(handler) });
Inspecting the GRPC channel before sending the request shows the request version is 1.1 (regardless of AppContext settings and TargetFramework):
The GRPC client libraries are:
Grpc.Net.Client v. 2.42.0
Grpc.Net.Client.Web v. 2.42.0
When the request is sent, the service side is logging the following in the output:
Exception thrown: 'Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException' in Microsoft.AspNetCore.Server.Kestrel.Core.dll
Exception thrown: 'Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException' in System.Private.CoreLib.dll
'TradingOrchestrationService.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.5\Microsoft.AspNetCore.WebUtilities.dll'.
Exception thrown: 'System.Net.Sockets.SocketException' in Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll
The I/O operation has been aborted because of either a thread exit or an application request.
The key thing I'd like to stress is the only difference between working and non-working behaviour is bumping up TargetFramework version in the entry assembly from 3.1 to 5 or 6.
For completeness and future reference I am posting the replies that I got from JamesNK on GitHub https://github.com/dotnet/runtime/issues/71906
When using HTTP then the client and server must use the same protocol.
Without https then there is no negotiation.
What protocol is Kestrel configured to use? HTTP/1.1 or HTTP/2? If you
haven't explicitly configured it to only HTTP/2 then it will probably
be HTTP/1.1.
GrpcWebHandler has a HttpVersion property on it that you can set to
explicitly specify what HTTP version you want. You could try setting
it to new Version(1, 1).
Does setting this property have any other implications?
And when we migrate the server to use HTTP/2, I suppose it will have to be removed?
Yes
What happened to you: in .NET Core 3.x the gRPC client was configuring
the gRPC request to be HTTP/2, but because you weren't using TLS the
request was silently downgraded to HTTP/1.1
That was fixed in .NET 5+, but you were relying on broken behavior so
the fix broke you.
The client is now sending HTTP/2 over http, but your server is
configured for HTTP/1.1. That creates a protocol error.
GrpcWebHandler.HttpVersion provides a way for you to override the HTTP
version and to specify exactly what you want (because gRPC-Web works
with both HTTP versions).

how to know why WCF service stopped

We have developed WCF service and hosted as windows service. We have written .net core client application.
We have observed that the service is not responding after a few calls. It gets stopped somehow.
I tried to create logging and trace in WCF service but it is not creating any .svclog file.
In exception handling, it gives the following message
Exception: One or more errors occurred. (An error occurred while
sending the request.) System.ServiceModel.CommunicationException: An
error occurred while sending the request. --->
System.Net.Http.HttpRequestException: An error occurred while sending
the request. ---> System.IO.IOException: Unable to read data from the
transport connection: An existing connection was forcibly closed by
the remote host.. ---> System.Net.Sockets.SocketException (10054): An
existing connection was forcibly closed by the remote host. --- End
of inner exception stack trace --- at
System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError
error, CancellationToken cancellationToken) at
System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16
token) at
System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage
request, CancellationToken cancellationToken)
I want to know what forced the service to be stopped? How can I find this?

Getting "System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly." error while calling web api

In my application, there is a functionality to extract reports based on a date range. In the background, it is calling my Web API with authentication(A), which consists of api caller functionality using httpclient, which is calling another non-secured DMZ server API (B) and a DMZ API-caliing WCF service (C) to collect data from the database.
My problem is that whenever I select a large date range, I get the following error in my WebAPI (A).
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at LRAS.OrderServices.Core.Helpers.ApiCaller.d__4.MoveNext()
What I have tried: I have increased the httpclient timeout from 300 to 1000 seconds, but it is breaking nearly every minute.
You can try several methods:
1.Configure the service point security protocol and select the SecurityProtocolType that suits you (Tls12, Ssl3, Tls, Tls11).
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
C# System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send
2.Set the ConnectionClose property of HttpClient.
_client.DefaultRequestHeaders.ConnectionClose = true;
HttpClient throwing "An error occurred while sending the request."
3.Try to hold the request long enough for it to complete normally and receive a valid response.
_client.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
_client.DefaultRequestHeaders.Add("Keep-Alive", "3600");
.NET HttpClient - An existing connection was forcibly closed by the remote host

ParseExceptions not getting thrown for CallFunctionAsync

I recently updated my client sdk to parse 1.6.2 for xamarin, and I noticed that ParseExceptions are no longer getting thrown properly.
When calling something like this:
string result = await ParseCloud.CallFunctionAsync<string>( "function" )
If that function calls response.error I get:
System.Net.WebException The remote server returned an error: (400) Bad Request.
Raw
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x0005e] in /Users/builder/data/lanes/2377/73229919/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:944
Where as in the pass it would generate a ParseException with the contents of the response.error. The WebException also does not have an inner exception to inspect.
I also thought it had something to do with my cloud code, but I find a similar problem with user login. A bad password generates this exception now:
System.Net.WebException The remote server returned an error: (404) Not Found.
Raw
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x0005e] in /Users/builder/data/lanes/2377/73229919/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:944
A few other things were upgraded when I updated the parse sdk. I'm now using xamarin forms 2.* instead of 1.5.* and I think the mono system libraries were also updated.

WCF REST SOAP web service - unauthorized error

I get this error. I have WCF REST SOAP web service thats supposed to fetch data from sharepoint list using sharepoint API and output it in json format. it works well on test server but not on iis production server.
System.Data.Services.Client.DataServiceQueryException: An error occurred while p
rocessing this request. ---> System.Data.Services.Client.DataServiceClientExcept
ion: Unauthorized
at System.Data.Services.Client.QueryResult.ExecuteQuery(DataServiceContext co
ntext)
at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServi
ceContext context, QueryComponents queryComponents)
--- End of inner exception stack trace ---
at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServi
ceContext context, QueryComponents queryComponents)
at System.Data.Services.Client.DataServiceQuery`1.Execute()
at System.Data.Services.Client.DataServiceQuery1.GetEnumerator()
at WCF_SOAP_REST_Service.Service.MapColumnValues_Events(IEnumerable1 items,
String language)
how to fix it?

Categories

Resources