Я использую консольное приложение для выполнения объемных тестов, в этих тестах я вызываю маршрут JobTitles, который я создал внутри API, в данном случае контроллер, который обрабатывает этот маршрут.
Для Функция публикации, которую я использую, я применил метод HttpClient PostAsJsonAsync()
. Поскольку я уже использовал эту функцию в другом коде, у меня не было много проблем, но теперь она возвращает исключение System.Net.Http.HttpRequestException: An error occurred while sending the request.
Я не использую вызов .Result
, так как это может привести к тупик; Я также пробовал использовать .ConfigureAwait (false)
, и это не сработало. Я также пытался работать с Easy.Common RestClient () , но возникла та же ошибка, у меня заканчиваются варианты того, в чем может быть ошибка. Извините, но я не могу понять, в чем заключается ошибка, просто взглянув на трассировку стека, я все еще не научился, как это понять.
Я поместил здесь код для лучшего просмотра, поскольку он немного большой:
https://repl.it/repls/JubilantMoccasinArrays
Я попытался создать общий метод c, поскольку в другом коде я сделал сообщение для каждой сущности, взяв Преимущество вопроса, я хотел бы знать, есть ли еще один, кроме RestClient и HttpClient, который я мог бы использовать для отправки нескольких вызовов, не вызывая отмены поставок из-за множества записей API, поскольку он автоматически отменяется, чтобы избежать DDoS.
И трассировка стека, которую я получаю от RestClient:
Unhandled exception. System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.IO.IOException: The response ended prematurely.
at System.Net.Http.HttpConnection.FillAsync()
at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at CodenApp.Studio2Me.VolumeTest.UsefulFunctions.HTTPFunctions`1.Post(String route, T content) in C:\Users\Yasmin Kruger\Documents\Studio2Me\Studio2Me\Tests\CodenApp.Studio2Me.VolumeTest\UsefulFunctions\HTTPFunctions.cs:line 29
at CodenApp.Studio2Me.VolumeTest.Classes.JobTitleData.JobTitleDataGenerator(Int32 x) in C:\Users\Yasmin Kruger\Documents\Studio2Me\Studio2Me\Tests\CodenApp.Studio2Me.VolumeTest\Classes\JobTitleData.cs:line 21
at CodenApp.Studio2Me.VolumeTest.Program.Main(String[] args) in C:\Users\Yasmin Kruger\Documents\Studio2Me\Studio2Me\Tests\CodenApp.Studio2Me.VolumeTest\Program.cs:line 22
at CodenApp.Studio2Me.VolumeTest.Program.<Main>(String[] args)
EDIT1 :
Я просто отправляю один запрос, чтобы проверить, работает ли он, Мне нужно отправить как минимум x * 6 JobTitles, не считая, что есть еще классы, которые нужно отправить вместе, поэтому мне нужен способ отправки большого количества запросов к API.
EDIT2 :
Трассировка стека из HttpClient:
System.Net.Http.HttpRequestException: An error occurred while sending the request.
---> System.IO.IOException: The response ended prematurely.
at System.Net.Http.HttpConnection.FillAsync()
at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at CodenApp.Studio2Me.VolumeTest.UsefulFunctions.HTTPFunctions`1.PostTest(String route, T content) in C:\Users\Yasmin Kruger\Documents\Studio2Me\Studio2Me\Tests\CodenApp.Studio2Me.VolumeTest\UsefulFunctions\HTTPFunctions.cs:line 51
EDIT3:
Main.cs:
using System;
using CodenApp.Studio2Me.VolumeTest.Classes;
using CodenApp.Studio2Me.VolumeTest.UsefulFunctions;
namespace CodenApp.Studio2Me.VolumeTest
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
// await JobTitleData.JobTitleDataGenerator(1);
await JobTitleData.JobTitleDataGenerator2(1);
}
}
}
HTTPFunction.cs:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Easy.Common.Extensions;
using Easy.Common.Interfaces;
using Newtonsoft.Json;
using Shouldly;
using RestClient = Easy.Common.RestClient;
namespace CodenApp.Studio2Me.VolumeTest.UsefulFunctions
{
public class HTTPFunctions<T> where T : class
{
const string APIAddress = "http://localhost:5001/";
public static async Task Post(string route, T content)
{
var endpointUri = new Uri(APIAddress + route);
ServicePointManager.FindServicePoint(endpointUri).ConnectionLeaseTimeout.ShouldBe(-1);
var jsonContent = JsonConvert.SerializeObject(content);
var contentString = new StringContent(jsonContent, Encoding.UTF8, "application/json");
contentString.Headers.ContentType = new MediaTypeHeaderValue("application/json");
using IRestClient client = new RestClient();
HttpResponseMessage response = await client.PostAsync(endpointUri, contentString); //This won't work too
//client.Timeout.ShouldBe(15.Seconds()); Sometimes cause an TimeOut Exception
Console.WriteLine(response);
}
public static async Task PostTest(string route, T content)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(APIAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage response = await client.PostAsJsonAsync(route, content).ConfigureAwait(false); //still not working
if(!response.IsSuccessStatusCode)
{
Console.WriteLine(content);
}
}
catch(Exception e)
{
//Using this just to get exception
Console.WriteLine(e.Message);
}
}
}
}
}
JobTitleData.cs:
using System;
using System.Threading.Tasks;
using Bogus;
using CodenApp.Studio2Me.Core.Entities.StoreEntities;
using CodenApp.Studio2Me.VolumeTest.UsefulFunctions;
namespace CodenApp.Studio2Me.VolumeTest.Classes
{
public class JobTitleData
{
public static async Task JobTitleDataGenerator(int x)
{
var faker = new Faker("pt_BR");
for(int i = 0; i < x; i++)
{
JobTitle jobTitle = new JobTitle();
jobTitle.Name = faker.Name.JobTitle();
jobTitle.StoreId = 1;
await HTTPFunctions<JobTitle>.Post("v1/Store/JobTitles", jobTitle);
}
}
public static async Task JobTitleDataGenerator2(int x)
{
var faker = new Faker("pt_BR");
for(int i = 0; i < x; i++)
{
JobTitle jobTitle = new JobTitle();
jobTitle.Name = faker.Name.JobTitle();
jobTitle.StoreId = 1;
await HTTPFunctions<JobTitle>.PostTest("v1/Store/JobTitles", jobTitle);
}
}
}
}
Несколько изменений в коде обсуждались с @Andy, и то же самое вернуло для меня ту же ошибку, я провожу тест на других машинах и пытаюсь вызвать тот же маршрут через Insomnia, чтобы проверить, не что-то еще не настроено. На данный момент он считает, что это мешает серверу, поскольку я не могу вернуть даже ответ объекта.
Предлагаемые изменения:
using (var msg = new HttpRequestMessage(HttpMethod.Post, new UriBuilder(APIAddress) { Path = route }.Uri))
{
msg.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
using (var resp = await _client.SendAsync(msg))
{
resp.EnsureSuccessStatusCode();
await resp.Content.ReadAsStringAsync();
}
}
}
}
EDIT4:
После стольких испытаний и использования разных программ для вызова маршрута я заметил, что это действительно проблема сервера, точнее HTTP-сертификации, потому что это тот, который блокирует вызов. Я внесу изменения в проект для получения дополнительной информации, а в edit5 я верну то, что было решено, и отправлю ответ, чтобы завершить этот вопрос.