asp.net-coredata-bindingdotnet-httpclientnancy

HttpClient not sending post data to NancyFX endpoint


I am doing some integration testing of my web API that uses NancyFX end points. I have the xUnit test create a test server for the integration test

 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();
    }

Inside a Test Method I tried the following

   [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);
    }

The NancyFX module does trigger the endpoint and receives the request but without the body

Img1

What am I doing wrong? Note that the NancyFX endpoint has no issue transforming a Postman call into a valid model.

The NancyFX endpoint enter image description here


Solution

  • Alright I fixed it, for those curious the issue was that the NancyFX body reader sometimes does not properly start reading the request body. That is that the stream reading position isn't 0 (the start) all the time.

    To fix this you need to create a CustomBoostrapper and then override the ApplicationStartup function so you can set up a before request pipeline that sets the body position at 0

    Code below

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