HTTPClient.PostAsync. Exception: Connection was closed unexpectedly. C# - c#

When I try to PostAsync, no response is coming back, even though the content is coming through.
The connection closes after 20 seconds or so, giving me an exception.
I'm getting a 200 OK, when Posting in Postman.
This is the code calling the method with .Wait:
StringContent sc = new StringContent(xml, Encoding.UTF8, "application/xml");
var t = Task.Factory.StartNew(() => MyAsyncMethod(sc, ao.orderId).Wait());
t.Wait();
t.Dispose();
This is the method:
public async Task MyAsyncMethod(StringContent sc, string orderid)
{
try
{
var response = await client.PostAsync("www.url.com", sc);
}
catch (Exception e)
{
using (StreamWriter writer = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "/Log/PostException.txt"))
{
writer.WriteLine(e.Message);
}
}
}
The Exception:
An error occurred while sending the request. at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at ShipNoticeInvoiceAPI.BLL.ShipNoticeGenerator.<SendShipNotice>d__4.MoveNext()
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)
System.Collections.ListDictionaryInternal
-2146233088
mscorlib
Void ThrowForNonSuccess(System.Threading.Tasks.Task)
I hope that you have tried something simular and are able to help me out. I feel like I've tried everything.

Related

.NET GoogleDrive API v3: persistent "connection was closed" errors

Uploading files via FilesResource.Update or FilesResource.Create is regularly emitting IOExceptions with message "System.IO.IOException: Unable to read data from the transport connection: The connection was closed." Is there any chance I can prevent these IOExceptions from happening?
The uploads seem to succeed, eventually, probably because this is happening within the ResumableUpload facility in the API. But (maybe anecdotally) it's causing not-insignificant performance issues; at times the queue of work being processed by our upload processes slows to almost a standstill, with these errors being logged incessantly.
Utility for uploading streams to Drive:
public async Task UploadFile(Stream uploadStream, string filename, string parentFolderId, string mimeType="", CancellationToken token = default(CancellationToken))
{
try
{
// File information for where this content will end up - name, folder, mime type
var fileMetaData = new File();
fileMetaData.Name = filename;
fileMetaData.MimeType = mimeType;
// check if file by this name exists with same parent and not trashed
var results = await ListFiles($"mimeType!='{FolderMimeType}' and name='{filename}' and '{parentFolderId}' in parents and trashed=false", token);
if (results.Count > 0)
{
log.Debug($"Overwrite existing fileid {results[0].Id} \"{results[0].Name}\" in parent {parentFolderId}");
var request = driveService.Files.Update(fileMetaData, results[0].Id, uploadStream, fileMetaData.MimeType);
request.Fields = "id, name";
request.ProgressChanged += Upload_ProgressChanged;
request.ResponseReceived += Upload_ResponseReceived;
request.SupportsAllDrives = true; // required in order to be able to upload to shared drive
await request.UploadAsync(token);
}
else
{
log.Debug($"No existing file found, uploading {filename} to parent {parentFolderId}");
fileMetaData.Parents = new List<string> { parentFolderId };
// send the stream to the destination file and dispose when finished
var request = driveService.Files.Create(fileMetaData, uploadStream, fileMetaData.MimeType);
request.Fields = "id, name";
request.ProgressChanged += Upload_ProgressChanged;
request.ResponseReceived += Upload_ResponseReceived;
request.SupportsAllDrives = true; // required in order to be able to upload to shared drive
await request.UploadAsync(token);
}
}
catch (Exception e)
{
throw e;
}
finally
{
uploadStream.Dispose();
}
}
These exceptions are caught in the "ProgressChanged" event, where the upload's status gets marked as Failed even though it does seem to be retried by the ResumableUpload part of the API:
static void Upload_ProgressChanged(IUploadProgress progress)
{
log.Debug($"Status: {progress.Status}, {BytesToString(progress.BytesSent)} sent");
if (progress.Exception != null && progress.Status == Google.Apis.Upload.UploadStatus.Failed)
{
log.Error($"Upload failed: {progress.Exception.Message}", progress.Exception);
}
}
Log w/ stack trace:
2022-05-23 17:25:19,365|ERROR|62|Upload failed: Unable to read data from the transport connection: The connection was closed.
System.IO.IOException: Unable to read data from the transport connection: The connection was closed.
at System.Net.ConnectStream.EndRead(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Upload.ResumableUpload.UploadBuffer.<PopulateFromStreamAsync>d__11.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis\Upload\ResumableUpload.cs:line 844
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Upload.ResumableUpload.<PrepareBufferUnknownSizeAsync>d__81.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis\Upload\ResumableUpload.cs:line 720
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Upload.ResumableUpload.<SendNextChunkAsync>d__77.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis\Upload\ResumableUpload.cs:line 630
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Google.Apis.Upload.ResumableUpload.<UploadCoreAsync>d__74.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis\Upload\ResumableUpload.cs:line 572

HttpWebRequest async call execution order when exception occurs

I used HttpWebRequest to async call a web service, occasionally EndGetResponse() returns some exceptions. However, even I got the exception, the call is successful and the data are returned. The following is my code with error checking code removed. I got 4 log items and the order is like this:
The following result is returned: ...
GetResult is successful!
PostXML exception: ...
GetResult exception: ...
public async Task<string> GetResult(string xmlData)
{
try
{
string response = await PostXML(Url, xmlData).ConfigureAwait(false);
_logger.Log($"GetResult is successful!");
return response;
}
catch (Exception ex)
{
_logger.Log("GetResult exception: " + ex.ToString());
throw;
}
}
private async Task<string> PostXML(string destinationUrl, string requestXml)
{
try
{
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(requestXml);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)await Task.Factory
.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
if (response.StatusCode == HttpStatusCode.OK)
{
Stream responseStream = response.GetResponseStream();
string responseStr = new StreamReader(responseStream).ReadToEnd();
_logger.Log("The following result is returned: \r\n" + responseStr);
responseStream.Close();
return responseStr;
}
}
catch (Exception ex)
{
_logger.Log("PostXML exception: " + ex.ToString());
throw;
}
return null;
}
The exception is like this:
PostXML() exception: 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.EndGetResponse(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MyService.d__7.MoveNext()
I guess I haven't fully understood how HttpWebRequest works in async mode. Anyway I hope these questions can help me to understand it more:
1. Why does the execution continue even an exception occurs? In my understanding, there should only have 2 log items to log the exception.
2. What is the reason the exception "The underlying connection was closed" occurs? Why does the exception occur but the service still gave back the correct result?
Why does the execution continue even an exception occurs? In my understanding, there should only have 2 log items to log the exception.
This isn't possible. I suspect your code is calling GetResult twice. That's what the log seems to indicate.
What is the reason the exception "The underlying connection was closed" occurs?
This happens when the server closes the connection before the client is ready for it to be closed. This is an unusual error to get from a REST API, but not unheard of.

WebException: The remote server returned an error: NotFound Windows Phone Youtube Html

I wanted to get elements and tags inside of youtube search results with below code for windows phone application.
public partial class Page1 : PhoneApplicationPage
{
string keyword;
public Page1()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
NavigationContext.QueryString.TryGetValue("parameter", out keyword);
LoadResults();
}
public void LoadResults()
{
WebClient codeSampleReq = new WebClient();
codeSampleReq.DownloadStringCompleted += codeSampleReq_DownloadStringCompleted;
codeSampleReq.DownloadStringAsync(new Uri("https://www.youtube.com/results?search_query=" + keyword));
}
void codeSampleReq_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.OptionFixNestedTags = true;
htmlDoc.LoadHtml(e.Result);
HtmlNode divContainer = htmlDoc.GetElementbyId("a");
if (divContainer != null)
{
HtmlNodeCollection nodes = divContainer.SelectNodes("a");
foreach (HtmlNode trNode in nodes)
{
}
}
}
catch (Exception ex)
{
MessageBox.Show("Unable to download" + ex.Message);
}
}
}
and get exception below:
{System.Net.WebException: The remote server returned an error:
NotFound. ---> System.Net.WebException: The remote server returned an
error: NotFound. at
System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult
asyncResult) at
System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.b__d(Object
sendState) at
System.Net.Browser.AsyncHelper.<>c__DisplayClass1.b__0(Object
sendState) --- End of inner exception stack trace --- at
System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback
beginMethod, Object state) at
System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult
asyncResult) at System.Net.WebClient.GetWebResponse(WebRequest
request, IAsyncResult result) at
System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult
result)}
does anybody know why server return 404 not found?
note: Keyword can only be string like "ali, veli, kadir" or something else.
NotFound is WebClient`s response many kinds of errors. The two most common cases are
bad server certificate (should not be your case, Youtube has a valid certificate)
no Internet connection in your emulator or device.
I almost sure your case is the second one, check your Internet connection.

Async/Await HttpClient request

I have a next code in a class, this class gets data from server in XML format:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.Cryptography.Certificates;
using Windows.Storage;
using Windows.Storage.Streams;
namespace TestProj.WebServiceModels
{
public class MyClient
{
async public static Task<string> fetchContentAsync()
{
string url = "https://blabla.com/test/data?format=xml";
HttpClientHandler aHandler=new HttpClientHandler();
aHandler.ClientCertificateOptions=ClientCertificateOption.Automatic;
HttpClient aClient=new HttpClient(aHandler);
Uri requestUri=new Uri(url);
HttpRequestMessage request=new HttpRequestMessage(HttpMethod.Get, requestUri);
var result=await aClient.GetAsync(requestUri, HttpCompletionOption.ResponseContentRead);
var responseHeader=result.Headers;
var responseBody=await result.Content.ReadAsStringAsync();
return responseBody;
}
}
}
On my Main Page i have a function that triggers get method AND IT FAILS!!!:
public MainPage()
{
this.InitializeComponent();
fillChartsObject();
}
private async void fillChartsObject()
{
try
{
var response = await MyClient.fetchContentAsync();
responseString = response.ToString();
}
catch
{
var dlg = new MessageDialog("You are totaly screwed!");
dlg.ShowAsync();
}
}
But when i do it on Button click it runs! How can that be?! How to fix it?
When it fails - it doesn't ask me which certificate to use, in other - does;
Error:
The request was aborted: Could not create SSL/TLS secure channel.
System.Net.Http.HttpRequestException не обработано пользовательским кодом
HResult=-2146233088
Message=An error occurred while sending the request.
Source=mscorlib
StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SaC.WebServiceModels.MyClient.<fetchContentAsync>d__0.MoveNext() in c:\Users\C5195923\Documents\Visual Studio 2012\Projects\SaC\SaC\WebServiceModels\MyClient.cs:line 31
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SaC.MainPage.<fillChartsObject>d__96.MoveNext() in c:\Users\foma\Documents\Visual Studio 2012\Projects\SaC\SaC\MainPage.xaml.cs:line 1546
InnerException: System.Net.WebException
HResult=-2146233079
Message=The request was aborted: Could not create SSL/TLS secure channel.
Source=System
StackTrace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
InnerException:
CODE 2:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
fillChartsObject();
}
private async void fillChartsObject()
{
String responseString = "";
var response = await MyClient.fetchContentAsync();
responseString = response.ToString();
}
ERRORS:
System.Net.Http.HttpRequestException не обработано пользовательским кодом
HResult=-2146233088
Message=An error occurred while sending the request.
Source=mscorlib
StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SAPSalesCentral.WebServiceModels.MyClient.<fetchContentAsync>d__0.MoveNext() in c:\Users\C5195923\Desktop\NewNewRevision\SAPSalesCentral\SAPSalesCentral\WebServiceModels\MyClient.cs:line 31
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SAPSalesCentral.MainPage.<fillChartsObject>d__94.MoveNext() in c:\Users\foma\Desktop\NewNewRevision\SAPSalesCentral\SAPSalesCentral\MainPage.xaml.cs:line 1539
InnerException: System.Net.WebException
HResult=-2146233079
Message=The request was aborted: Could not create SSL/TLS secure channel.
Source=System
StackTrace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
InnerException:
Additional functions:
ShowLoadingScreen(); // displays semi-transparent background over the whole form and progressRing (native Windows 8 spinner) on it.
GetSettings(); //gets data from local settings storage;
CheckFileExists(); // ASYNC! Checks if data is already stored on a device, if not, gets from web
fillListBox(); // Just populates listbox with hardcoded data;
PopulateHelpMenu(); // Just populates listbox with hardcoded data;
(App.Current as App).Main = this;
Edit:
public MainPage()
{
this.InitializeComponent();
//#region Initialization
ShowLoadingScreen();
//fillChartsObject();
GetSettings();
CheckFileExists();
fillListBox();
PopulateHelpMenu();
(App.Current as App).Main = this;
//#endregion
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
await Task.Delay(5000);
await fillChartsObject();
//await fillChartsObject();
//fillChartsObject();
////dtm = DataTransferManager.GetForCurrentView();
////dtm.DataRequested += OnDataRequested;
////SettingsPane.GetForCurrentView().CommandsRequested += BlankPage_CommandsRequested;
}
private async void CheckFileExists()
{
//vpnAvailability = await VPN.Check(); //When i uncoment this - it fails again. This just sends request to a link, if it fails = no VPN if not = is VPN.
ro = new List<RootObject>();
StorageFile File;
try
{
#region If file exists
File = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("UserData.txt");
if (File != null)
{
string JSON = await FileIO.ReadTextAsync(File);
if (JSON != "")
{
//If file exists get data
try
{
ro = JsonConvert.DeserializeObject<List<RootObject>>(JSON);
fillGamificationLine(ro);
}
catch
{
getGamificationDataFromServer();
}
}
else
{
throw new FileNotFoundException();
}
}
#endregion
}
catch (FileNotFoundException)
{
//If file doesn't exist - get data from server
getGamificationDataFromServer();
}
}
//The idea was that when all UserData is being populated from server or locally, the request of table data (only from service) is being proceeded parallel.
Thanks to Kris Vandermotten i have ran into this magic:
Fails:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
await fillChartsObject();
}
Works:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
await Task.Delay(1);
await fillChartsObject();
}
This is probably a timing issue, where your code runs too early. You should let the UI initialisation code complete first.
Try this:
public MainPage()
{
this.InitializeComponent();
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
// allow other queued messages to be processed first
// this may work as well: await Task.Yield();
await Task.Delay(1);
// now continue
await fillChartsObject();
}
private async void fillChartsObject()
{
try
{
var response = await MyClient.fetchContentAsync();
responseString = response.ToString();
}
catch
{
var dlg = new MessageDialog("You are totally screwed!");
dlg.ShowAsync();
}
}

Simplest possible sample to connect selfhosted signalR-server and client?

I'm trying to connect a client to a self-hosted SignalR-server.
My server looks like this:
static void Main(string[] args)
{
string url = "http://localhost:8081/";
var server = new Server(url);
server.MapConnection<MyConnection>("/echo");
server.Start();
Console.WriteLine("Server running on {0}", url);
Console.ReadKey();
}
public class MyConnection : PersistentConnection
{
}
It was the simplest I could came up with. And the client looks like this:
static void Main(string[] args)
{
SignalR.Client.Connection conn = new SignalR.Client.Connection("http://localhost:8081/echo");
Task start = conn.Start();
start.Wait();
if (start.Status == TaskStatus.RanToCompletion)
{
Console.WriteLine("Connected");
}
Console.ReadKey();
}
I can't get the code above to work. The server start, but when I run the client code to connect I got an error:
The remote server returned an error: (500) Internal Server Error.
And the server is also giving me an error: Cannot access a disposed object.
Have I forgot something? What am I doing wrong?
Edit:
The error I get on the server is the following....
SignalRtest.vshost.exe Error: 0 : A first chance exception of type 'System.AggregateException' occurred in mscorlib.dll
SignalR exception thrown by Task: System.AggregateException: One or more errors occurred. ---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.HttpListenerResponse'.
at System.Net.HttpListenerResponse.CheckDisposed()
at System.Net.HttpListenerResponse.get_OutputStream()
at SignalR.Hosting.Self.Infrastructure.ResponseExtensions.<>c_DisplayClass4.b_1(IAsyncResult ar)
at System.Threading.Tasks.TaskFactory.FromAsyncCoreLogic(IAsyncResult iar, Action1 endMethod, TaskCompletionSource1 tcs)
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.HttpListenerResponse'.
at System.Net.HttpListenerResponse.CheckDisposed()
at System.Net.HttpListenerResponse.get_OutputStream()
at SignalR.Hosting.Self.Infrastructure.ResponseExtensions.<>c_DisplayClass4.b_1(IAsyncResult ar)
at System.Threading.Tasks.TaskFactory.FromAsyncCoreLogic(IAsyncResult iar, Action1 endMethod, TaskCompletionSource1 tcs)<---
'client.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.DebuggerVisualizers\10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.DebuggerVisualizers.dll'
Looks like it's disposing the server variable because it doesn't see it being used later in the function. Add GC.KeepAlive( server ) to the end of your Main function to make sure it doesn't get disposed of early. Or better yet, but it in a using statement.

Categories

Resources