I have three layer application architecture.
My Client —> My service A (REST hosted in IIS) —> Other Team’s service X (REST).
Service A is ASP.Net 4.6.1 framework, not ASP.Net Core.
Client is communicating to A with HttpClient and A is communicating to X with HttpClient.
Client is firing almost 2500 calls to my service to A and to X.
Out of 2500 calls service A randomly (may be 10 calls) fails with below exception. Its not reproducible.
System.Net.Http.HttpRequestException: An error occurred while sending the request. --->
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a
receive. ---> System.IO.IOException: Unable to read data from the transport connection: An
established connection was aborted by the software in your host machine. --->
System.Net.Sockets.SocketException: An established connection was aborted by the software in your
host machine
at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags
socketFlags, AsyncCallback callback, Object state)
at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback
callback, Object state)
--- End of inner exception stack trace ---
at System.Net.Security._SslStream.EndRead(IAsyncResult asyncResult)
at System.Net.TlsStream.EndRead(IAsyncResult asyncResult)
at System.Net.Connection.ReadCallback(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace --
Here is my service A call. A in IIS calls below code block and its called by each request. X is taking user credentials and returning data based on user, so we are not sharing HttpClient between calls.
var user = (System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity;
System.Security.Principal.WindowsIdentity.RunImpersonated(user.AccessToken, () =>
{
static HttpClient Client = new HttpClient();
static string CallX(string[] args)
{
HttpClientHandler handler = new HttpClientHandler
{
UseDefaultCredentials = true
};
Client = new HttpClient(handler)
{
BaseAddress = new Uri("http://XserviceUrl/api/")
};
Client.Timeout = TimeSpan.FromSeconds(600);
var result = Client.PostAsync("Fake X controller"
, new StringContent(JsonConvert.SerializeObject(args)
, Encoding.UTF8, "application/json")).Result;
result.EnsureSuccessStatusCode();
var json = result.Content.ReadAsStringAsync().Result;
return DosomethingWithResult(json);
}
});
Things I tried:
Some SO post suggested might be timeout issue. So I added 600 seconds in Client and in Service A. I also changed IIS request timeout from default 2 minutes to 10 (600 seconds).
I was having a WebClient
that was requesting an URL. I wanted to do the same thing within a UWP application, and I saw that I had to import Microsoft.Net.Http
and use HttpClient
.
So I replaced this(that was in a Class library):
WebClient client = new WebClient();
client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
string content = client.DownloadString(url);
By this in a PCL library:
HttpClient client = new HttpClient();
string content = await client.GetStringAsync(url);
And now I got this exception:
System.Net.Http.HttpRequestException occurred
HResult=-2147012867
Message=An error occurred while sending the request.
Source=System.Net.Http
StackTrace:
at System.Net.Http.HttpClientHandler.<SendAsync>d__1.MoveNext()
--- 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 XXXX.YYYY.MHDJ.ZZZZ.<ParsePage>d__4.MoveNext()
InnerException:
ErrorCode=-2147012867
HResult=-2147012867
Message=Le texte associé à ce code d’erreur est introuvable.
Impossible d'établir une connexion avec le serveur
Source=""
StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpHandlerToFilter.<SendAsync>d__1.MoveNext()
--- 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.Net.Http.HttpClientHandler.<SendAsync>d__1.MoveNext()
InnerException:
I don’t think the issue is the Headers, so what is?
asked Apr 14, 2016 at 19:05
1
The HRESULT
code -2147012867
in hex is 0x80072EFD
. The 0x8007
prefix means it’s actually an HRESULT
wrapper around a Win32
error code. The original Win32
error code is 0x2EFD
.
The Win32
error code list tells us that values 0x2EE0
through 0x2F8F
are ERROR_INTERNET_*
error codes, which sounds like the right kind of error. After following the link to the Win32
ERROR_INTERNET_*
error code listing, we can convert our error code 0x2EFD
back to decimal (12029
) and discover it is error ERROR_INTERNET_CANNOT_CONNECT
:
The attempt to connect to the server failed.
Rather generic, and not much help.
I’d recommend trying the connection again, ensuring that your application has appropriate permissions and the device actually has a working Internet connection. If that doesn’t work, try adding the UserAgent
header back in; it’s possible that the networking stack on your device insists on it.
Update: Tracking down the error code meaning was rather tedious, so I wrote an app to do it.
answered Apr 14, 2016 at 19:42
Stephen ClearyStephen Cleary
433k76 gold badges668 silver badges801 bronze badges
7
Experienced the 0x80072efd problem. Has cost me hours if not days to solve. The solution that worked for me was the following command from an admin command prompt:
netsh winhttp reset proxy
answered Aug 5, 2016 at 11:07
Paul0515Paul0515
23k9 gold badges31 silver badges47 bronze badges
0
There are so many ways to do things, and I’m not suggesting that this is the best way, but this is how I construct my methods. This example is what I use to return a list of U.S. State objects that are provided in JSON format. One important note… this is in a Universal Windows class library, not a PCL… but I do not believe it uses anything that a PCL does not have access to.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Threading.Tasks;
//IStateInfo is my model class interface
public async Task<IList<IStateInfo>> GetAllStatesAsync()
{
List<IStateInfo> states = new List<IStateInfo>();
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://YourBaseApiHere");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string url = "lookup/usstates";
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
//deserialize into client class Newtonsoft JSON used here
var lst = JsonConvert.DeserializeObject<List<StateInfo>>(json);
states.AddRange(lst);
}
else
{
//notify of failed web call here
}
}
}
catch (Exception e)
{
//notify of error
}
return states;
}
answered Apr 15, 2016 at 13:26
Mark WMark W
1,0507 silver badges15 bronze badges
4
Description
randomly fails, sometimes they do all work correctly.
System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.IO.IOException: The response ended prematurely.
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
at Essensoft.AspNetCore.Payment.WeChatPay.V2.Extensions.HttpClientExtensions.PostAsync[T](HttpClient client, IWeChatPayRequest`1 request, IDictionary`2 textParams)
at Essensoft.AspNetCore.Payment.WeChatPay.V2.WeChatPayClient.ExecuteAsync[T](IWeChatPayRequest`1 request, WeChatPayOptions options)
at lambda_method72(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Configuration
.NET SDK (reflecting any global.json):
Version: 5.0.101
Commit: d05174dc5a
Runtime Environment:
OS Name: debian
OS Version: 10
OS Platform: Linux
RID: debian.10-x64
Base Path: /usr/share/dotnet/sdk/5.0.101/
Host (useful for support):
Version: 5.0.1
Commit: b02e13abab
.NET SDKs installed:
5.0.101 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 5.0.1 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.1 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
#c# #asp.net-web-api #http-post #httpclient
#c# #asp.net-web-api #http-post #httpclient
Вопрос:
Я работаю над простой консольной программой, которая использует веб-сервис (http). Будет отправлять строки json из текстового файла.
Протестировал приведенный ниже фрагмент на моем собственном API, который работал нормально.
Использовал postman для отправки запроса в api и получил ответ.
static void Main(string[] args)
{
//System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;
HttpClient client = new HttpClient(); //should be instatiated once per application
do
{
try
{
Console.WriteLine("Enter Method:");
string Method = Console.ReadLine();
Console.WriteLine("Enter URI:");
string uri = Console.ReadLine();
if (("POST,PUT").Split(',').Contains(Method.ToUpper()))
{
Console.WriteLine("Enter FilePath:");
string FilePath = Console.ReadLine();
iLog.Log(iLog.EVENT, string.Format(" {0} | {1}", "File Path : <", FilePath ">"));
string str_content = (File.OpenText(@FilePath)).ReadToEnd();
iLog.Log(iLog.EVENT, string.Format(" {0} | {1}", "String data : <", str_content ">"));
//StringContent class creates a formatted text appropriate for the http server/client communication
StringContent httpContent = new StringContent(str_content, System.Text.Encoding.UTF8, "application/json");
iLog.Log(iLog.EVENT, string.Format("1")); //trace
try
{
//Some risky client call that will call parallell code / async /TPL or in some way cause an AggregateException
var postTask = client.PostAsync(uri, httpContent);
iLog.Log(iLog.EVENT, string.Format("2")); //trace
postTask.Wait();
iLog.Log(iLog.EVENT, string.Format("3")); //trace
//gets the response back from the API service
HttpResponseMessage result = postTask.Resu<
iLog.Log(iLog.EVENT, string.Format("4")); //trace
if (result.IsSuccessStatusCode)
{
iLog.Log(iLog.EVENT, string.Format("5")); //trace
//use this if you want a raw json string
var readTask = result.Content.ReadAsStringAsync();
iLog.Log(iLog.EVENT, string.Format("6")); //trace
readTask.Wait();
iLog.Log(iLog.EVENT, string.Format("7")); //trace
var str_Response = readTask.Result.ToString();
iLog.Log(iLog.EVENT, string.Format("8")); //trace
Console.WriteLine("WebService Response : n<" str_Response ">");
iLog.Log(iLog.EVENT, string.Format(" {0} | {1}", "WebService Response : <", str_Response ">"));
}
else
{
Console.WriteLine("Status Code = " result.StatusCode);
iLog.Log(iLog.EVENT, string.Format(" {0} | {1}", "StatusCode", result.StatusCode));
iLog.Log(iLog.EVENT, string.Format("9")); //trace
}
}
catch (AggregateException err)
{
foreach (var errInner in err.InnerExceptions)
{
iLog.Log(iLog.ERROR, string.Format(errInner.ToString())); //trace
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
iLog.Log(iLog.EVENT, string.Format("{0} | {1}", "Exception", ex.Message.ToString()));
iLog.Log(iLog.EVENT, string.Format("10")); //trace
}
iLog.Log(iLog.EVENT, string.Format("{0} {1}", "END", "----------------------------" "n"));
Console.WriteLine("Do you want to continue?");
} while (Console.ReadLine().ToUpper() == "Y");
}
Возвращена ошибка:
System.Net.Http.HttpRequestException: при отправке запроса произошла ошибка. —> System.Net.WebException: базовое соединение было закрыто: соединение было неожиданно закрыто. в System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult AsyncResult, TransportContextamp; context) в System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) — Конец трассировки стека внутренних исключений —
Комментарии:
1. В Postman вы используете POST или PUT?
2. использовался post
3. Я не знаю, является ли этот комментарий грубым или нет. Но, пожалуйста, взгляните на соглашение об именовании для c # docs.microsoft.com/en-us/dotnet/csharp/programming-guide /… Это показывает, как вы уважаете зрителя
4. отмеченное исправит, все еще довольно новое.
5. На самом деле вы также можете изменить сигнатуру основного метода
public static async Task Main(string[] args)
, чтобы иметь возможность использовать async/await вместо .Wait/.Result
Ответ №1:
Привет смог заставить его работать, используя предложение Caius Jard об использовании добавления nuget restsharp и замене сгенерированным Postman кодом.
Pilarentes 621 / 385 / 135 Регистрация: 06.03.2017 Сообщений: 1,445 |
||||||||
1 |
||||||||
Проверка, что ссылка не битая17.07.2019, 17:18. Показов 4437. Ответов 4 Метки нет (Все метки)
Нашел вот такой метод, но он выдает исключение. Что можно подправить? вызов метода:
сам метод:
0 |
215 / 149 / 48 Регистрация: 28.12.2016 Сообщений: 716 |
|
17.07.2019, 17:52 |
2 |
Pilarentes, try catch блок
0 |
621 / 385 / 135 Регистрация: 06.03.2017 Сообщений: 1,445 |
|
17.07.2019, 19:30 [ТС] |
3 |
Defences, Вы не поняли. Я хочу понять, почему так происходит, чтобы исправить ошибку.
0 |
215 / 149 / 48 Регистрация: 28.12.2016 Сообщений: 716 |
|
17.07.2019, 20:44 |
4 |
Pilarentes, вам же искл. говорит об этом «Не удалось создать защищенный канал SSL/TLS.»
0 |
Pilarentes 621 / 385 / 135 Регистрация: 06.03.2017 Сообщений: 1,445 |
||||
17.07.2019, 22:36 [ТС] |
5 |
|||
РешениеРазобрался. Надо добавить вот такую строку было
1 |