HttpClient не отправляет данные post в конечную точку NancyFX

#api #asp.net-core #data-binding #httpclient #nancy

#API #asp.net-core #привязка данных #httpclient #нэнси

Вопрос:

Я провожу некоторое интеграционное тестирование своего веб-API, который использует конечные точки NancyFX. У меня есть тест xUnit, создающий тестовый сервер для интеграционного теста

  private readonly TestServer _server;
    private readonly HttpClient _client;

    public EventsModule_Int_Tester()
    {
        //Server setup
        _server = new TestServer(new WebHostBuilder()
      .UseStartup<Startup>());
        _server.AllowSynchronousIO = true;//Needs to be overriden in net core 3.1
        _client = _server.CreateClient();
    }
  

Внутри метода тестирования я попробовал следующее

    [Fact]
    public async Task EventTest()
    {
        // Arrange
        HttpResponseMessage expectedRespone = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
        var data = _server.Services.GetService(typeof(GenijalnoContext)) as GenijalnoContext;

        //Get come random data from the DBcontext
        Random r = new Random();
        List<Resident> residents = data.Residents.ToList();
        Resident random_residnet = residents[r.Next(residents.Count)];

        List<Apartment> apartments = data.Apartments.ToList();
        Apartment random_Apartment = apartments[r.Next(apartments.Count)];



        EventModel model = new EventModel()
        {
            ResidentId = random_residnet.Id,
            ApartmentNumber = random_Apartment.Id

        };

        //Doesnt work
        IList<KeyValuePair<string, string>> nameValueCollection = new List<KeyValuePair<string, string>> {
        { new KeyValuePair<string, string>("ResidentId", model.ResidentId.ToString()) },
        { new KeyValuePair<string, string>("ApartmentNumber", model.ApartmentNumber.ToString())}
        };

        var result = await _client.PostAsync("/Events/ResidentEnter", new FormUrlEncodedContent(nameValueCollection));



        //Also Doesnt work 
        string json = JsonConvert.SerializeObject(model, Formatting.Indented);
        var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
        var response = await _client.PostAsync("/Events/ResidentEnter", httpContent);

        //PostAsJsonAsync also doesnt work 

        // Assert
        Assert.Equal(response.StatusCode, expectedRespone.StatusCode);
    }
  

Модуль NancyFX запускает конечную точку и получает запрос, но без тела

Img1

Что я делаю не так? Обратите внимание, что конечная точка NancyFX не имеет проблем с преобразованием вызова Postman в допустимую модель.

Конечная точка NancyFX введите описание изображения здесь

Комментарии:

1. Можете ли вы показать подпись API на /Events/ResidentEnter конечной точке?

2. @Andy обновил вопрос с помощью endpoint API

3. Вы сказали, что у PostMan нет проблем, можете ли вы также показать, что вы делаете в PostMan?

4. @Andy Я просто отправляю свойства EventModel в качестве параметров через тело в форме form-data. Обратите внимание, что работают как form-data, так и x-www-form-urlencoded. Я могу добавить картинку, если вы хотите

5. Если это работает в PostMan, но здесь это не работает… И ваша фактическая конечная точка попадает в ваши тесты (означает, что ваш хост httpclient настроен правильно), тогда должно быть, что вы отправляете данные не так, как в PostMan.

Ответ №1:

Хорошо, я исправил это, для любопытных проблема заключалась в том, что программа чтения тела NancyFX иногда неправильно начинает чтение тела запроса. Это означает, что позиция чтения потока не всегда равна 0 (начало).

Чтобы исправить это, вам нужно создать CustomBoostrapper, а затем переопределить функцию ApplicationStartup, чтобы вы могли настроить конвейер перед запросом, который устанавливает положение тела на 0

Код ниже

     protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
    {
        base.ApplicationStartup(container, pipelines);
        pipelines.BeforeRequest.AddItemToStartOfPipeline(ctx =>
        {
            ctx.Request.Body.Position = 0;
            return null;
        });


    }